Condividi tramite


Plug-in di NuGet multipiattaforma

In NuGet 4.8+ è stato aggiunto il supporto per plug-in multipiattaforma. Ciò è stato ottenuto creando un nuovo modello di estendibilità del plug-in, che deve essere conforme a un set rigoroso di regole di funzionamento. I plugin sono applicazioni eseguibili autonome, chiamate eseguibili nel contesto di .NET Core, che i client NuGet lanciano in un processo separato. Questo è un plugin davvero scrivi una volta, eseguibile ovunque. Funzionerà con tutti gli strumenti client NuGet. I plug-in possono essere scritti in qualsiasi linguaggio di programmazione, ma l'esperienza di sviluppo e installazione dei plug-in più semplice sarà con .NET. Viene definito un protocollo di comunicazione con controllo delle versioni tra il client NuGet e il plug-in. Durante la stretta di mano all'avvio, i due processi negoziano la versione del protocollo.

Come funziona

Il flusso di lavoro di alto livello può essere descritto come segue:

  1. NuGet individua i plug-in disponibili.
  2. Quando applicabile, NuGet eseguirà l'iterazione dei plug-in in ordine di priorità e li avvierà uno per uno.
  3. NuGet userà il primo plug-in in in grado di eseguire la richiesta.
  4. I plug-in verranno arrestati quando non sono più necessari.

Requisiti generali del plug-in

La versione corrente del protocollo è 2.0.0. In questa versione, i requisiti sono i seguenti:

  • Supportare l'avvio senza stato nel contesto di sicurezza corrente degli strumenti client NuGet. Ad esempio, gli strumenti client NuGet non eseguiranno l'elevazione dei privilegi o l'inizializzazione aggiuntiva all'esterno del protocollo del plug-in descritto più avanti.
  • Essere non interattivo, a meno che non sia specificato in modo esplicito.
  • Attenersi alla versione del protocollo del plug-in negoziata.
  • Rispondere a tutte le richieste entro un periodo di tempo ragionevole.
  • Rispettare le richieste di annullamento per qualsiasi operazione in corso.

I plug-in individuati dalla variabile di ambiente PATH (ad esempio, installati tramite dotnet tool) devono corrispondere anche al modello nuget-plugin-*di nome file . La nuget-plugin- parte deve essere scritta interamente in lettere minuscole.

NuGet 6.12 (MSBuild 17.12 e .NET SDK 9.0.100) e versioni precedenti richiedevano anche che i plug-in fossero firmati con Authenticode su Windows.

La specifica tecnica è descritta in modo più dettagliato nelle specifiche seguenti:

Client - Interazione con plug-in

Gli strumenti client NuGet e i plug-in comunicano con JSON su flussi standard (stdin, stdout, stderr). Tutti i dati devono essere codificati con UTF-8. I plug-in vengono avviati con l'argomento "-Plugin". Nel caso in cui un utente avvii direttamente un eseguibile del plug-in senza questo argomento, il plug-in può mostrare un messaggio informativo invece di attendere un protocollo di handshake. Il timeout dell'handshake del protocollo è di 5 secondi. Il plug-in dovrebbe completare la configurazione nel minor tempo possibile. Gli strumenti client NuGet interrogheranno le operazioni supportate di un plug-in passando l'indice del servizio per una sorgente NuGet. Un plug-in può usare l'indice del servizio per verificare la presenza di tipi di servizio supportati.

La comunicazione tra gli strumenti client NuGet e il plug-in è bidirezionale. Ogni richiesta ha un timeout di 5 secondi. Se le operazioni devono richiedere più tempo, il rispettivo processo deve inviare un messaggio di stato per impedire il timeout della richiesta. Dopo 1 minuto di inattività, un plug-in viene considerato inattivo e viene arrestato.

Installazione e individuazione dei plug-in

NuGet cerca plug-in da una struttura di directory basata su convenzioni e analizza la variabile di ambiente PATH.

Individuazione basata su convenzioni

Gli scenari CI/CD e gli utenti esperti possono usare le variabili di ambiente per eseguire l'override del comportamento. Quando si usano variabili di ambiente, sono consentiti solo percorsi assoluti. Si noti che NUGET_NETFX_PLUGIN_PATHS e NUGET_NETCORE_PLUGIN_PATHS sono disponibili solo con la versione 5.3+ degli strumenti NuGet e versioni successive.

  • NUGET_NETFX_PLUGIN_PATHS: definisce i plug-in che verranno usati dagli strumenti basati su .NET Framework (NuGet.exe/MSBuild.exe/Visual Studio). Ha la precedenza su NUGET_PLUGIN_PATHS. (solo NuGet versione 5.3+)
  • NUGET_NETCORE_PLUGIN_PATHS : definisce i plug-in che verranno usati dagli strumenti basati su .NET Core (dotnet.exe). Ha la precedenza su NUGET_PLUGIN_PATHS. (solo NuGet versione 5.3+)
  • NUGET_PLUGIN_PATHS : definisce i plug-in che verranno usati per il processo NuGet, con priorità mantenuta. Se questa variabile di ambiente è impostata, sostituisce l'individuazione basata sulla convenzione. Ignorato se viene specificata una delle variabili specifiche del framework.
  • Posizione utente, posizione della home page NuGet in %UserProfile%/.nuget/plugins. Non è possibile eseguire l'override di questo percorso. Verrà utilizzata una diversa directory principale per i plug-in di .NET Core e .NET Framework.
Struttura Posizione di individuazione della radice Usato da
.NET Core %UserProfile%/.nuget/plugins/netcore Interfaccia della riga di comando dotnet
.NET Framework %UserProfile%/.nuget/plugins/netfx MSBuild, NuGet.exe, Visual Studio

Ogni plug-in deve essere installato nella propria cartella. Il punto di ingresso del plug-in sarà il nome della cartella installata, con le estensioni .dll per .NET Core e l'estensione .exe per .NET Framework.

.nuget
    plugins
        netfx
            myPlugin
                myPlugin.exe
                nuget.protocol.dll
                ...
        netcore
            myPlugin
                myPlugin.dll
                nuget.protocol.dll
                ...

Scoperta del percorso

A partire da NuGet 6.13, NuGet cercherà ogni directory fornita nella variabile di ambiente PATH per trovare i file corrispondenti al modello nuget-plugin-*. La corrispondenza dei criteri fa distinzione tra maiuscole e minuscole e nuget-plugin- deve essere scritta interamente in lettere minuscole. In Windows il file deve avere un'estensione .exe o .bat . In Linux e Mac il file deve avere il bit eseguibile impostato.

In questo modo, i plug-in NuGet possono essere installati tramite dotnet tool comandi, WinGet, gestione pacchetti di una distribuzione Linux o qualsiasi altro metodo in grado di inserire eseguibili nel percorso dell'utente. In questo modo i plug-in NuGet possono essere scritti in qualsiasi linguaggio di programmazione (in precedenza i plug-in per Linux e Mac devono essere scritti in .NET).

È consigliabile sviluppare plug-in in .NET, in modo che sia possibile usare il pacchetto NuGet.Protocol per evitare di dover scrivere il codice RPC JSON e consentire ai clienti di individuare il plug-in tramite dotnet package search nuget-plugin.

Operazioni supportate

Nel nuovo protocollo plug-in sono supportate due operazioni.

Nome operazione Versione minima del protocollo Versione minima del client NuGet
Scaricare il pacchetto 1.0.0 4.3.0
Autenticazione 2.0.0 4.8.0

Esecuzione di plug-in nel runtime corretto

Per gli scenari NuGet in dotnet.exe, i plug-in devono essere in grado di essere eseguiti sotto quel runtime specifico di dotnet.exe. È responsabilità del provider del plug-in e del consumatore assicurarsi che venga utilizzata una combinazione compatibile di dotnet.exe/plug-in. Un potenziale problema potrebbe verificarsi con i plug-in di posizione utente quando, ad esempio, un dotnet.exe nel runtime 2.0 tenta di usare un plug-in scritto per il runtime 2.1.

Memorizzazione nella cache delle funzionalità

La verifica di sicurezza e la creazione di istanze dei plug-in è costosa. L'operazione di download avviene più frequentemente rispetto all'operazione di autenticazione, ma è probabile che l'utente NuGet medio abbia solo un plug-in di autenticazione. Per migliorare l'esperienza, NuGet memorizza nella cache le attestazioni dell'operazione per la richiesta specificata. Questa cache è per plug-in con la chiave del plug-in che rappresenta il percorso del plug-in e la scadenza per questa cache delle funzionalità è di 30 giorni.

La cache si trova in %LocalAppData%/NuGet/plugins-cache e può essere sovrascritta con la variabile di ambiente NUGET_PLUGINS_CACHE_PATH. Eseguire il comando locals con l'opzione per cancellare questa plugins-cache. L'opzione all variabili locali ora eliminerà anche la cache dei plug-in.

Indice dei messaggi del protocollo

Versione protocollo 1.0.0 messaggi:

  1. Chiudi

    • Direzione richiesta: NuGet - plugin>
    • La richiesta non conterrà alcun payload
    • Non è prevista alcuna risposta. La risposta corretta è che il processo di plug-in venga immediatamente chiuso.
  2. Copiare i file nel pacchetto

    • Direzione richiesta: NuGet - plugin>
    • La richiesta conterrà:
      • ID e versione del pacchetto
      • percorso del repository di origine del pacchetto
      • percorso della directory di destinazione
      • un elenco di file nel pacchetto da copiare nel percorso della directory di destinazione
    • Una risposta conterrà:
      • un codice di risposta che indica il risultato dell'operazione
      • un elenco enumerabile di percorsi completi per i file copiati nella directory di destinazione se l'operazione riesce
  3. Copiare il file del pacchetto (con estensione nupkg)

    • Direzione richiesta: NuGet - plugin>
    • La richiesta conterrà:
      • ID e versione del pacchetto
      • percorso del repository di origine del pacchetto
      • percorso del file di destinazione
    • Una risposta conterrà:
      • un codice di risposta che indica il risultato dell'operazione
  4. Ottenere le credenziali

    • Direzione richiesta: plug-in -> NuGet
    • La richiesta conterrà:
      • percorso del repository di origine del pacchetto
      • il codice di stato HTTP ottenuto dal repository di origine del pacchetto usando le credenziali correnti
    • Una risposta conterrà:
      • un codice di risposta che indica il risultato dell'operazione
      • un nome utente, se disponibile
      • una password, se disponibile
  5. Recuperare i file nel pacchetto

    • Direzione richiesta: NuGet - plugin>
    • La richiesta conterrà:
      • ID e versione del pacchetto
      • percorso del repository di origine del pacchetto
    • Una risposta conterrà:
      • un codice di risposta che indica il risultato dell'operazione
      • un enumerabile di percorsi dei file nel pacchetto se l'operazione ha avuto esito positivo
  6. Ottenere le attestazioni dell'operazione

    • Direzione richiesta: NuGet - plugin>
    • La richiesta conterrà:
      • il servizio index.json per una sorgente del pacchetto
      • percorso del repository di origine del pacchetto
    • Una risposta conterrà:
      • un codice di risposta che indica il risultato dell'operazione
      • enumerabile di operazioni supportate (ad esempio: download di pacchetti) se l'operazione ha avuto esito positivo. Se un plug-in non supporta l'origine del pacchetto, il plug-in deve restituire un set vuoto di operazioni supportate.

Nota

Questo messaggio è stato aggiornato nella versione 2.0.0. Spetta al client mantenere la compatibilità con le versioni precedenti.

  1. Ottenere l'hash del pacchetto

    • Direzione richiesta: NuGet - plugin>
    • La richiesta conterrà:
      • ID e versione del pacchetto
      • percorso del repository di origine del pacchetto
      • algoritmo hash
    • Una risposta conterrà:
      • un codice di risposta che indica il risultato dell'operazione
      • l'hash del file del pacchetto utilizzando l'algoritmo hash richiesto se l'operazione è riuscita
  2. Ottenere le versioni dei pacchetti

    • Direzione richiesta: NuGet - plugin>
    • La richiesta conterrà:
      • l'ID del pacchetto
      • percorso del repository di origine del pacchetto
    • Una risposta conterrà:
      • un codice di risposta che indica il risultato dell'operazione
      • un enumerabile di versioni di pacchetti nel caso in cui l'operazione abbia avuto esito positivo
  3. Ottenere l'indice del servizio

    • Direzione richiesta: plug-in -> NuGet
    • La richiesta conterrà:
      • percorso del repository di origine del pacchetto
    • Una risposta conterrà:
      • un codice di risposta che indica il risultato dell'operazione
      • indice del servizio se l'operazione ha avuto esito positivo
  4. Stretta di mano

    • Direzione richiesta: plugin NuGet <->
    • La richiesta conterrà:
      • versione corrente del protocollo del plug-in
      • versione minima del protocollo di plug-in supportato
    • Una risposta conterrà:
      • un codice di risposta che indica il risultato dell'operazione
      • versione del protocollo negoziata se l'operazione ha avuto esito positivo. Un errore comporterà la chiusura del plug-in.
  5. Inizializzare

    • Direzione richiesta: NuGet - plugin>
    • La richiesta conterrà:
      • Versione dello strumento client NuGet
      • il linguaggio efficace dello strumento client NuGet. Questa impostazione prende in considerazione l'impostazione ForceEnglishOutput, se usata.
      • timeout della richiesta predefinito, che sostituisce l'impostazione predefinita del protocollo.
    • Una risposta conterrà:
      • codice di risposta che indica il risultato dell'operazione. Un errore comporterà la chiusura del plug-in.
  6. Registro

    • Direzione richiesta: plug-in -> NuGet
    • La richiesta conterrà:
      • livello di registro per la richiesta
      • un messaggio da registrare
    • Una risposta conterrà:
      • codice di risposta che indica il risultato dell'operazione.
  7. Monitorare l'uscita del processo NuGet

    • Direzione richiesta: NuGet - plugin>
    • La richiesta conterrà:
      • ID del processo NuGet
    • Una risposta conterrà:
      • codice di risposta che indica il risultato dell'operazione.
  8. Pacchetto di prelettura

    • Direzione richiesta: NuGet - plugin>
    • La richiesta conterrà:
      • ID e versione del pacchetto
      • percorso del repository di origine del pacchetto
    • Una risposta conterrà:
      • un codice di risposta che indica il risultato dell'operazione
  9. Impostare le credenziali

    • Direzione richiesta: NuGet - plugin>
    • La richiesta conterrà:
      • percorso del repository di origine del pacchetto
      • l'ultimo nome utente dell'origine del pacchetto noto, se disponibile
      • l'ultima password di origine del pacchetto nota, se disponibile
      • l'ultimo nome utente proxy noto, se disponibile
      • l'ultima password proxy nota, se disponibile
    • Una risposta conterrà:
      • un codice di risposta che indica il risultato dell'operazione
  10. Impostare il livello di log

    • Direzione richiesta: NuGet - plugin>
    • La richiesta conterrà:
      • livello di log predefinito
    • Una risposta conterrà:
      • un codice di risposta che indica il risultato dell'operazione

Messaggi del protocollo versione 2.0.0

  1. Ottenere attestazioni dell'operazione
  • Direzione richiesta: NuGet - plugin>

    • La richiesta conterrà:
      • il servizio index.json per una sorgente del pacchetto
      • percorso del repository di origine del pacchetto
    • Una risposta conterrà:
      • un codice di risposta che indica il risultato dell'operazione
      • un elenco di operazioni supportate se l'operazione ha avuto esito positivo. Se un plug-in non supporta l'origine del pacchetto, il plug-in deve restituire un set vuoto di operazioni supportate.

    Se l'indice del servizio e l'origine del pacchetto sono Null, il plug-in può rispondere con l'autenticazione.

  1. Ottenere le credenziali di autenticazione
  • Direzione richiesta: NuGet - plugin>
  • La richiesta conterrà:
    • Uri
    • isRetry
    • Non Interattivo
    • PuòMostrareDialogo
  • Una risposta conterrà
    • Nome utente
    • Parola d’ordine
    • Messaggio
    • Elenco dei tipi di autenticazione
    • CodiceRispostaMessaggio