> For the complete documentation index, see [llms.txt](https://cristiandis.gitbook.io/ntix/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://cristiandis.gitbook.io/ntix/ntix-documentation/docs-it/api/execution.md).

# ExecutionEngine

## ExecutionEngine

Applica un diff calcolato invocando i comandi del gestore di pacchetti.

```rust
use ntix_rs::execution::execution_engine;
```

### apply\_diff

```rust
#[allow(clippy::too_many_arguments)]
pub async fn apply_diff(
    diff: &DiffResult,
    options: &NTIXOptions,
    state: &mut State,
    state_path: &Path,
    stop_on_failure: bool,
    validation: &ValidationResult,
    apply_config: bool,
    on_output: Option<LineCallback<'_>>,
    on_error: Option<LineCallback<'_>>,
    runner: Option<&dyn CommandRunner>,
) -> bool
```

Dove `LineCallback<'a> = &'a (dyn Fn(&str) + Sync)`.

| Parametro         | Tipo                         | Predefinito  | Descrizione                                                    |
| ----------------- | ---------------------------- | ------------ | -------------------------------------------------------------- |
| `diff`            | `&DiffResult`                | obbligatorio | Diff calcolato da eseguire                                     |
| `options`         | `&NTIXOptions`               | obbligatorio | Opzioni del gestore di pacchetti                               |
| `state`           | `&mut State`                 | obbligatorio | Stato mutabile; aggiornato sul posto                           |
| `state_path`      | `&Path`                      | obbligatorio | Percorso per rendere persistente lo stato dopo ogni operazione |
| `stop_on_failure` | `bool`                       | `false`      | Interrompi al primo errore                                     |
| `validation`      | `&ValidationResult`          | obbligatorio | Verifica delle capacità del gestore dalla fase di diff         |
| `apply_config`    | `bool`                       | `false`      | Applica `configFiles` azioni                                   |
| `on_output`       | `Option<LineCallback>`       | `None`       | Callback di stdout                                             |
| `on_error`        | `Option<LineCallback>`       | `None`       | Callback di stderr                                             |
| `runner`          | `Option<&dyn CommandRunner>` | `None`       | Esecutore dei comandi; usa `ProcessCommandRunner` se `None`    |

**Restituisce:** `bool` - true se tutte le operazioni sono riuscite.

### Ordine di esecuzione

1. Riporta gli avvisi di convalida del gestore che non sono già in `diff.warnings` tramite `on_error`
2. Garantisce che i bucket di scoop vengano aggiunti e che i bucket orfani vengano rimossi (se scoop è abilitato)
3. Installa i pacchetti (`to_install`)
4. Aggiorna i pacchetti (`to_upgrade`)
5. Rimuove gli orfani (`to_remove`)
6. Adotta i pacchetti (`to_adopt`) - solo stato, nessuna installazione
7. Applica `configFiles` (`to_create` e `to_update` vengono copiati da src a dest; gli orfani vengono rimossi dal tracciamento senza toccare il disco) - solo quando `apply_config` è true
8. Salva lo stato dopo ogni operazione riuscita

Le operazioni per un gestore disabilitato vengono saltate. Se `stop_on_failure` è true, l'esecuzione si arresta alla prima operazione fallita.

### Recupero dagli errori

Alcuni gestori terminano con codice diverso da zero anche in caso di esito positivo: winget segnala come errore l'installazione di un pacchetto già installato, e la disinstallazione con choco/scoop di un pacchetto assente si comporta in modo simile. Dopo qualsiasi installazione o aggiornamento fallito, `apply_diff` interroga di nuovo l'elenco dei pacchetti installati e considera l'operazione riuscita se il pacchetto è presente; dopo una rimozione fallita, la considera riuscita se viene confermato che il pacchetto è assente. Una query dell'elenco fallita viene trattata come un errore, mai come un falso positivo.

### Blocco

`apply_diff` non acquisisce il lock autonomamente. Il lock viene eseguito dal chiamante (il binario acquisisce un `LockFile` prima di invocare `apply_diff`).
