in focus/operations/src/selection.rs [83:182]
fn mutate(
sparse_repo: impl AsRef<Path>,
sync_if_changed: bool,
action: OperationAction,
projects_and_targets: Vec<String>,
app: Arc<focus_util::app::App>,
) -> Result<bool> {
let mut synced = false;
let repo = Repo::open(sparse_repo.as_ref(), app.clone())?;
let mut selections = repo.selection_manager().context("Loading the selection")?;
let backup = if sync_if_changed {
Some(
selections
.create_backup()
.context("Creating a backup of the current selection")?,
)
} else {
None
};
let mut projects_and_targets = projects_and_targets;
match action {
OperationAction::Add(AddOptions { unroll: true }) => {
let mut projects = vec![];
let mut targets = vec![];
for i in projects_and_targets.clone() {
if Target::try_from(i.as_str()).is_ok() {
targets.push(i);
} else {
projects.extend(
selections
.project_catalog()
.optional_projects
.underlying
.get(&i)
.with_context(|| {
format!("Couldn't find project definition for {}.", i)
})?
.projects
.clone(),
);
targets.extend(
selections
.project_catalog()
.optional_projects
.underlying
.get(&i)
.with_context(|| {
format!("Couldn't find project definition for {}.", i)
})?
.targets
.clone(),
);
};
}
projects_and_targets = targets;
projects_and_targets.extend(projects);
}
OperationAction::Remove(RemoveOptions { all: true }) => {
let projects: Vec<String> = selections
.selection()?
.projects
.into_iter()
.map(|x| x.name)
.collect();
let targets = selections
.selection()?
.targets
.into_iter()
.map(|x| match x {
Target::Bazel(c) => format!("bazel:{}", c),
Target::Directory(c) => format!("bazel:{}", c),
})
.collect();
projects_and_targets = targets;
projects_and_targets.extend(projects);
}
_ => (),
}
if selections
.mutate(action, &projects_and_targets)
.context("Updating the selection")?
{
selections.save().context("Saving selection")?;
if sync_if_changed {
info!("Synchronizing after selection changed");
// TODO: Use the correct sync mode here. Sync will override for SyncMode::Incremental, but that feels janky.
let result = super::sync::run(
&SyncRequest::new(sparse_repo.as_ref(), SyncMode::Incremental),
app,
)
.context("Synchronizing changes")?;
synced = result.status == super::sync::SyncStatus::Success;
backup.unwrap().discard();
}
}
Ok(synced)
}