{"id":32848,"date":"2019-10-31T21:49:16","date_gmt":"2019-10-31T18:49:16","guid":{"rendered":"https:\/\/prohoster.info\/blog\/vnedryajte-staticheskij-analiz-v-protsess-a-ne-ishhite-s-ego-pomoshhyu-bagi\/"},"modified":"2019-10-31T21:49:16","modified_gmt":"2019-10-31T18:49:16","slug":"vnedryajte-staticheskij-analiz-v-protsess-a-ne-ishhite-s-ego-pomoshhyu-bagi","status":"publish","type":"post","link":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/vnedryajte-staticheskij-analiz-v-protsess-a-ne-ishhite-s-ego-pomoshhyu-bagi","title":{"rendered":"Integra l'analisi statica nel tuo processo, invece di cercare bug con essa","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>La mia decisione di scrivere questo articolo \u00e8 stata ispirata dalla grande quantit\u00e0 di materiale sull'analisi statica che ho notato sempre pi\u00f9 spesso. Innanzitutto, si tratta del <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/en\/company\/pvs-studio\/blog\/\">blog PVS-studio<\/a><\/noindex>, che promuove attivamente se stesso su Habr attraverso recensioni di errori trovati dal loro strumento in progetti open source. Recentemente, PVS-studio ha implementato <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/en\/company\/pvs-studio\/blog\/436496\/\">il supporto per Java<\/a><\/noindex>, e naturalmente gli sviluppatori di IntelliJ IDEA, il cui analizzatore integrato \u00e8 attualmente probabilmente il pi\u00f9 avanzato per Java, <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/en\/company\/JetBrains\/blog\/436278\/\">non potevano rimanere indifferenti<\/a><\/noindex>. <\/p>\n<p>Quando leggi tali recensioni, si ha l'impressione di avere a che fare con una pozione magica: premi un pulsante e voil\u00e0 \u2014 un elenco di difetti davanti ai tuoi occhi. Sembra che con il miglioramento degli analizzatori, verranno trovati automaticamente sempre pi\u00f9 bug, e i prodotti scansionati da questi robot diventeranno sempre migliori, senza alcuno sforzo da parte nostra.<\/p>\n<p>Ma non esistono elisir magici. Vorrei parlare di ci\u00f2 di cui di solito non si discute nei post del tipo \u00abecco cosa pu\u00f2 trovare il nostro robot\u00bb: cosa non possono fare gli analizzatori, qual \u00e8 il loro ruolo e la loro posizione nel processo di fornitura del software e come implementarli correttamente.<\/p>\n<p><img decoding=\"async\" alt=\"Integra l&#039;analisi statica nel tuo processo, invece di cercare bug con essa\" src=\"\/wp-content\/uploads\/2019\/05\/2a0339f10edcaed3310676ab6e2f975a.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Il riduttore (fonte: <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A5%D1%80%D0%B0%D0%BF%D0%BE%D0%B2%D0%BE%D0%B9_%D0%BC%D0%B5%D1%85%D0%B0%D0%BD%D0%B8%D0%B7%D0%BC#\/media\/File:Sperrklinke_Schema.svg\">wikipedia<\/a><\/noindex>).<\/i><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Cosa non potranno mai fare gli analizzatori statici<\/h2>\n<p>\nChe cos'\u00e8, in termini pratici, l'analisi del codice sorgente? Forniamo alcuni sorgenti in input e in breve tempo (molto meno del tempo necessario per eseguire i test) otteniamo alcune informazioni sul nostro sistema. Il vincolo principale e matematicamente ineludibile \u00e8 che possiamo ottenere solo una classe abbastanza ristretta di informazioni in questo modo.<\/p>\n<p>Il pi\u00f9 famoso esempio di problema non risolvibile tramite analisi statica \u00e8 <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Halting_problem\">il problema dell'arresto<\/a><\/noindex>: \u00e8 un teorema che dimostra che non \u00e8 possibile sviluppare un algoritmo generale che, dati il codice sorgente di un programma, possa determinare se entrer\u00e0 in un ciclo infinito o terminer\u00e0 in un tempo finito. L'estensione di questo teorema \u00e8 <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Rice%27s_theorem\">il teorema di Rice<\/a><\/noindex>, che afferma che per qualsiasi propriet\u00e0 non banale delle funzioni calcolabili, definire se un programma arbitrario calcola una funzione con tale propriet\u00e0 \u00e8 un problema algoritmicamente irrisolvibile. Ad esempio, \u00e8 impossibile scrivere un analizzatore che, dato un codice sorgente qualsiasi, possa determinare se il programma analizzato \u00e8 un'implementazione di un algoritmo che calcola, ad esempio, il quadrato di un numero intero.<\/p>\n<p>Pertanto, la funzionalit\u00e0 degli analizzatori statici ha limiti ineludibili. Un analizzatore statico non potr\u00e0 mai determinare in tutti i casi situazioni come, ad esempio, il verificarsi di un 'null pointer exception' in linguaggi che consentono il valore null, o nei casi in cui si verifica un 'attribute not found' in linguaggi con tipizzazione dinamica. Ci\u00f2 che il pi\u00f9 sofisticato degli analizzatori statici pu\u00f2 fare \u00e8 evidenziare casi particolari, il cui numero rispetto a tutti i possibili problemi con il tuo codice sorgente \u00e8, senza esagerare, una goccia nel mare.<\/p>\n<h2>L'analisi statica non \u00e8 ricerca di bug<\/h2>\n<p>\nDalle informazioni fornite, si pu\u00f2 concludere che l'analisi statica non \u00e8 un mezzo per ridurre il numero di difetti nel software. Mi permetto di affermare che, se applicata per la prima volta al tuo progetto, essa individuer\u00e0 nel codice dei punti \"interessanti\", ma probabilmente non trover\u00e0 difetti che influenzino la qualit\u00e0 del funzionamento del tuo programma.<\/p>\n<p>Gli esempi di difetti automaticamente trovati dagli analizzatori sono impressionanti, ma non bisogna dimenticare che questi esempi sono stati scoperti tramite la scansione di un ampio set di grandi basi di codice. Allo stesso modo, i ladri informatici, che possono testare diverse semplici password su un gran numero di account, riescono infine a individuare quegli account che utilizzano una password semplice.<\/p>\n<p>Ci\u00f2 significa che l'analisi statica non deve essere applicata? Certamente no! E per lo stesso motivo per cui \u00e8 utile controllare ogni nuova password contro la lista nera delle \"password semplici\".<\/p>\n<h2>L'analisi statica \u00e8 molto pi\u00f9 di una semplice ricerca di bug.<\/h2>\n<p>\nIn realt\u00e0, le problematiche affrontate dall'analisi statica sono decisamente pi\u00f9 ampie. Infatti, l'analisi statica comprende qualsiasi verifica del codice sorgente effettuata prima della sua esecuzione. Ecco alcune delle operazioni che possono essere svolte:<\/p>\n<ul>\n<li> Controllo dello stile di codifica nel senso pi\u00f9 ampio del termine. Questo include non solo il controllo del formato, ma anche la ricerca di parentesi vuote o superflue, l'impostazione di soglie per metriche come il numero di righe o la complessit\u00e0 ciclica di un metodo, ecc. \u2014 tutto ci\u00f2 che pu\u00f2 potenzialmente ostacolare la leggibilit\u00e0 e la manutenibilit\u00e0 del codice. In Java, uno strumento di questo tipo \u00e8 Checkstyle, mentre in Python si utilizza flake8. Programmi di questa categoria sono comunemente chiamati \"linters\".<\/li>\n<li>Non solo il codice eseguibile pu\u00f2 essere analizzato. I file di risorse, come JSON, YAML, XML e .properties, possono (e devono!) essere automaticamente verificati per la validit\u00e0. \u00c8 meglio scoprire che la struttura JSON \u00e8 compromessa a causa di qualche virgolette non corrispondenti in una fase iniziale della verifica automatica del Pull Request, piuttosto che durante l'esecuzione dei test o in fase di runtime. Gli strumenti appropriati sono disponibili, ad esempio, <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/adrienverge\/yamllint\">YAMLlint<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/zaach\/jsonlint\">JSONLint<\/a><\/noindex>.<\/li>\n<li> La compilazione (o parsing per linguaggi di programmazione dinamici) \u00e8 anch'essa una forma di analisi statica. In genere, i compilatori sono in grado di emettere avvisi che segnalano problemi di qualit\u00e0 nel codice sorgente, e non devono essere ignorati.<\/li>\n<li>Talvolta la compilazione non \u00e8 solo la generazione di codice eseguibile. Ad esempio, se hai documentazione in formato <noindex><a rel=\"nofollow\" href=\"https:\/\/asciidoctor.org\/\">AsciiDoctor<\/a><\/noindex>, al momento della conversione in HTML\/PDF, il gestore AsciiDoctor (<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/asciidoctor\/asciidoctor-maven-plugin\">plugin Maven<\/a><\/noindex>) pu\u00f2 emettere avvisi, ad esempio, su riferimenti interni non validi. Questo \u00e8 un motivo concreto per non accettare una Pull Request con modifiche alla documentazione.<\/li>\n<li>Il controllo ortografico \u00e8 anch'esso una forma di analisi statica. L'utilit\u00e0 <noindex><a rel=\"nofollow\" href=\"http:\/\/aspell.net\/\">aspell<\/a><\/noindex> pu\u00f2 verificare l'ortografia non solo nella documentazione, ma anche nel codice sorgente dei programmi (nei commenti e nelle stringhe) in vari linguaggi di programmazione, tra cui C\/C++, Java e Python. Un errore di ortografia nell'interfaccia utente o nella documentazione \u00e8 anch'esso un difetto!<\/li>\n<li>I test di configurazione (per cosa sia - vedere <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=KaeEjsAjV6A&amp;index=30&amp;list=PLsVTVVvrKX9tuYyCtL8mASB6IOaa-kRCA&amp;t=0s\">questo<\/a><\/noindex> e <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=Tk_nmV-mWOA\">questo<\/a><\/noindex> I report), anche se vengono eseguiti in un ambiente di test modulari tipo pytest, sono in realt\u00e0 una forma di analisi statica, poich\u00e9 non eseguono il codice sorgente durante la loro esecuzione.<\/li>\n<\/ul>\n<p>\nCome possiamo vedere, la ricerca di bug in questo elenco gioca un ruolo minore, mentre tutto il resto \u00e8 accessibile tramite strumenti open source gratuiti.<\/p>\n<p>Quali di questi tipi di analisi statica dovreste applicare al vostro progetto? Certamente tutti, pi\u00f9 ce ne sono, meglio \u00e8! L'importante \u00e8 implementare correttamente, di cui parleremo di seguito.<\/p>\n<h2>Il pipeline di distribuzione come un filtro a pi\u00f9 livelli e l'analisi statica come il suo primo strato<\/h2>\n<p>\nUna metafora classica dell'integrazione continua \u00e8 il pipeline, attraverso cui scorrono le modifiche \u2014 dall'alterazione del codice sorgente fino alla distribuzione in produzione. La sequenza standard delle fasi di questo pipeline appare cos\u00ec:<\/p>\n<ol>\n<li>analisi statica<\/li>\n<li>compilazione<\/li>\n<li>test modulari<\/li>\n<li>test di integrazione<\/li>\n<li>test UI<\/li>\n<li>verifica manuale<\/li>\n<\/ol>\n<p>\nLe modifiche bocciate nella fase N del pipeline non vengono trasferite alla fase N+1.<\/p>\n<p>Perch\u00e9 proprio cos\u00ec, e non in un altro modo? Nella parte del pipeline dedicata ai test, i tester apprendono della ben nota piramide dei test.<\/p>\n<p><img decoding=\"async\" alt=\"Integra l&#039;analisi statica nel tuo processo, invece di cercare bug con essa\" src=\"\/wp-content\/uploads\/2019\/05\/f155307fd4c1663800843c394098ea6f.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Piramide dei test. Fonte: <noindex><a rel=\"nofollow\" href=\"https:\/\/martinfowler.com\/bliki\/TestPyramid.html\">articolo<\/a><\/noindex> Martin Fowler.<\/i><\/p>\n<p>Nella parte inferiore di questa piramide si trovano i test pi\u00f9 facili da scrivere, che si eseguono pi\u00f9 rapidamente e hanno una minore tendenza ai falsi positivi. Perci\u00f2 devono essere pi\u00f9 numerosi, coprire pi\u00f9 codice e essere eseguiti per primi. Nella parte superiore della piramide, la situazione \u00e8 opposta, pertanto il numero di test di integrazione e UI deve essere ridotto al minimo necessario. L'elemento umano in questa catena \u00e8 la risorsa pi\u00f9 costosa, lenta e inaffidabile, quindi si trova alla fine e svolge il lavoro solo se le fasi precedenti non hanno rilevato difetti. Tuttavia, la pipeline \u00e8 costruita secondo gli stessi principi anche nelle parti non direttamente collegate ai test!<\/p>\n<p>Vorrei suggerire un'analogia basata su un sistema di filtraggio dell'acqua a pi\u00f9 stadi. In ingresso, si introduce acqua sporca (modifiche con difetti), e in uscita dobbiamo ottenere acqua pulita, da cui sono stati eliminati tutti i contaminanti indesiderati.<\/p>\n<p><img decoding=\"async\" alt=\"Integra l&#039;analisi statica nel tuo processo, invece di cercare bug con essa\" src=\"\/wp-content\/uploads\/2019\/05\/76b5be8f13d55c16970d67e09767a045.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Filtro a pi\u00f9 stadi. Fonte: <noindex><a rel=\"nofollow\" href=\"https:\/\/commons.wikimedia.org\/wiki\/File:Milli-Q_Water_filtration_station.JPG\">Wikimedia Commons<\/a><\/noindex><\/i><\/p>\n<p>Come \u00e8 noto, i filtri per la purificazione sono progettati in modo tale che ogni stadio successivo possa trattenere frazioni sempre pi\u00f9 piccole di contaminanti. Gli stadi di filtraggio pi\u00f9 grossolani hanno una maggiore capacit\u00e0 e un costo inferiore. Nella nostra analogia, questo significa che i gate di qualit\u00e0 in ingresso hanno una maggiore velocit\u00e0, richiedono meno sforzo per l'attivazione e sono meno esigenti nel funzionamento \u2014 e sono disposti proprio in questo ordine. Il ruolo dell'analisi statica, che ora comprendiamo essere in grado di scartare solo i difetti pi\u00f9 grossolani, \u00e8 simile a quello della griglia \u00abintrappolatrice\u00bb all'inizio del cascame di filtri.<\/p>\n<p>L'analisi statica da sola non migliora la qualit\u00e0 del prodotto finale, cos\u00ec come un \"filtraggio\" non rende potabile l'acqua. Tuttavia, la sua importanza \u00e8 evidente quando \u00e8 combinata con altri elementi della catena di produzione. Anche se nei filtri multi-stadio i livelli di uscita possono teoricamente catturare tutto ci\u00f2 che si trova nei livelli di ingresso, \u00e8 chiaro quali conseguenze possano derivare dal tentativo di fare affidamento solo sui livelli di pulizia fine, senza i livelli di ingresso.<\/p>\n<p>L'obiettivo del \"filtraggio\" \u00e8 alleggerire i livelli successivi dalla cattura di difetti veramente grossolani. Ad esempio, almeno, la persona che esegue la revisione del codice non dovrebbe essere distratta da codice formattato in modo errato e da violazioni delle norme di codifica stabilite (come parentesi superflue o ramificazioni troppo profonde). I bug come NPE dovrebbero essere catturati dai test modulari, ma se gi\u00e0 prima del test l'analizzatore indica che un bug \u00e8 inevitabile, ci\u00f2 accelerer\u00e0 notevolmente la sua correzione.<\/p>\n<p>Credo che ora sia chiaro perch\u00e9 l'analisi statica non migliori la qualit\u00e0 del prodotto se utilizzata in modo episodico; deve essere applicata costantemente per escludere i cambiamenti con difetti gravi. La questione se l'uso di un analizzatore statico migliorer\u00e0 la qualit\u00e0 del tuo prodotto \u00e8 in gran parte equivalente alla domanda: \"migliorer\u00e0 la potabilit\u00e0 dell'acqua prelevata da uno stagno sporco se la si fa passare attraverso un colino?\"<\/p>\n<h2>Integrazione in un progetto legacy<\/h2>\n<p>\nUn'importante questione pratica: come integrare l'analisi statica nel processo di integrazione continua come \"quality gate\"? Nel caso dei test automatici \u00e8 tutto chiaro: c'\u00e8 un insieme di test e il fallimento di uno di essi \u00e8 una base sufficiente per ritenere che la build non abbia superato il quality gate. Tentare di stabilire un gate sui risultati dell'analisi statica fallisce: nel codice legacy ci sono troppi avvertimenti; non si vuole ignorarli completamente, ma non si pu\u00f2 fermare la consegna del prodotto solo perch\u00e9 ci sono avvertimenti dell'analizzatore.<\/p>\n<p>Quando viene utilizzato per la prima volta, l'analizzatore fornisce un'enorme quantit\u00e0 di avvisi, la maggior parte dei quali non sono rilevanti per il corretto funzionamento del prodotto. Non \u00e8 possibile correggere immediatamente tutti questi commenti e in molti casi non \u00e8 nemmeno necessario. Dopotutto, sappiamo che il nostro prodotto funziona complessivamente, e anche prima di implementare l'analisi statica!<\/p>\n<p>Di conseguenza, molti si limitano a un uso sporadico dell'analisi statica, oppure la utilizzano solo in modalit\u00e0 di segnalazione, quando durante la compilazione viene semplicemente generato un rapporto dall'analizzatore. Questo \u00e8 equivalente all'assenza di qualsiasi analisi, poich\u00e9 se abbiamo gi\u00e0 un certo numero di avvisi, l'emergere di un altro (per quanto grave) in seguito a modifiche del codice rimane inosservato.<\/p>\n<p>Sono noti i seguenti modi per introdurre quality gates:<\/p>\n<ul>\n<li>Impostazione di un limite sul numero totale di avvisi o sul numero di avvisi diviso per il numero di righe di codice. Questo metodo funziona male, poich\u00e9 un tale gate consente liberamente modifiche con nuovi difetti, finch\u00e9 il loro limite non viene superato.<\/li>\n<li>La registrazione, in un determinato momento, di tutti i vecchi avvisi nel codice come ignorati, e il rifiuto della compilazione in caso di nuovi avvisi. Questa funzionalit\u00e0 \u00e8 fornita da PVS-studio e alcune risorse online, come Codacy. Non ho avuto esperienza con PVS-studio, ma per quanto riguarda la mia esperienza con Codacy, il loro principale problema \u00e8 che determinare cosa sia un errore \"vecchio\" e cosa sia \"nuovo\" \u00e8 un algoritmo piuttosto complesso e non sempre funziona correttamente, specialmente se i file vengono modificati o rinominati significativamente. Ricordo che Codacy poteva ignorare nuovi avvisi in una pull request, e allo stesso tempo non approvare una pull request a causa di avvisi non relativi alle modifiche in quel codice.<\/li>\n<li>A mio avviso, la soluzione pi\u00f9 efficace \u00e8 quella descritta nel libro <noindex><a rel=\"nofollow\" href=\"https:\/\/www.amazon.com\/Continuous-Delivery-Deployment-Automation-Addison-Wesley\/dp\/0321601912\">Continuous Delivery<\/a><\/noindex> il \u00abmetodo dell'arresto\u00bb (\u00abratcheting\u00bb). L'idea principale \u00e8 che la caratteristica di ogni rilascio \u00e8 il numero di avvisi di analisi statica, e sono consentite solo quelle modifiche che non aumentano il numero totale di avvisi.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Arresto<\/h2>\n<p>\nFunziona in questo modo:<\/p>\n<ol>\n<li>Nella fase iniziale, viene registrato nei metadati del rilascio il numero di avvisi nel codice trovati dagli analizzatori. In questo modo, quando viene assemblata la branch principale, nel tuo gestore di repository non viene indicato solo \"rilascio 7.0.2\", ma \"rilascio 7.0.2, contenente 100500 avvisi di Checkstyle\". Se utilizzi un gestore di repository avanzato (come Artifactory), \u00e8 facile mantenere tali metadati sul tuo rilascio.<\/li>\n<li>Ora ogni pull request, durante la compilazione, confronta il numero di avvisi risultanti con quello presente nell'attuale rilascio. Se la PR porta a un incremento di questo numero, il codice non supera il quality gate dell'analisi statica. Se il numero di avvisi diminuisce o rimane invariato, allora passa.<\/li>\n<li>Con il prossimo rilascio, il numero ricalcolato di avvisi sar\u00e0 nuovamente registrato nei metadati del rilascio.<\/li>\n<\/ol>\n<p>\nCos\u00ec, poco a poco, ma inesorabilmente (come quando si utilizza un meccanismo a cricchetto), il numero di avvisi tende verso zero. Certo, il sistema pu\u00f2 essere ingannato introducendo un nuovo avviso e correggendo uno esistente. Questo \u00e8 normale, in quanto a lungo termine produce risultati: gli avvisi vengono corretti, di norma, non singolarmente, ma tutti insieme in base a un certo tipo, e tutti gli avvisi facilmente risolvibili vengono rapidamente rimossi.<\/p>\n<p>Questo grafico mostra il numero totale di avvisi Checkstyle in sei mesi di funzionamento di un tale \u00abmeccanismo a cricchetto\u00bb su <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/CourseOrchestra\/celesta\">uno dei nostri progetti OpenSource<\/a><\/noindex>. Il numero di avvisi \u00e8 diminuito drasticamente, e ci\u00f2 \u00e8 avvenuto in modo naturale, parallelamente allo sviluppo del prodotto!<\/p>\n<p><img decoding=\"async\" alt=\"Integra l&#039;analisi statica nel tuo processo, invece di cercare bug con essa\" src=\"\/wp-content\/uploads\/2019\/05\/9529bb2fb32187057088e8d2c4203333.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nUtilizzo una versione modificata di questo metodo, contando separatamente gli avvisi divisi per moduli del progetto e strumenti di analisi; il file YAML generato con i metadati sulla build appare all'incirca nel seguente modo:<\/p>\n<pre><code class=\"plaintext\">celesta-sql:\n  checkstyle: 434\n  spotbugs: 45\ncelesta-core:\n  checkstyle: 206\n  spotbugs: 13\ncelesta-maven-plugin:\n  checkstyle: 19\n  spotbugs: 0\ncelesta-unit:\n  checkstyle: 0\n  spotbugs: 0\n<\/code><\/pre>\n<p>\nIn any advanced CI system, a 'ratchet' can be implemented for any static analysis tools without relying on plugins or third-party tools. Each analyzer produces its report in a simple text or XML format, which is easy to analyze. You just need to script the necessary logic in the CI script. You can see how this is implemented in our open-source projects based on Jenkins and Artifactory. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/CourseOrchestra\/2bass\/blob\/dev\/Jenkinsfile\">qui<\/a><\/noindex> o <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/CourseOrchestra\/celesta\/blob\/dev\/Jenkinsfile\">qui<\/a><\/noindex>. Both examples depend on the library <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/inponomarev\/ratchetlib\">ratchetlib<\/a><\/noindex>: the method <code>countWarnings()<\/code> counts xml tags in files generated by Checkstyle and Spotbugs in the usual way, while <code>compareWarningMaps()<\/code> implements the ratchet itself, throwing an error if the number of warnings in any of the categories increases.<\/p>\n<p>Una realizzazione interessante di un \u00abcatalizzatore\u00bb \u00e8 possibile per analizzare l'ortografia di commenti, letterali di testo e documentazione utilizzando aspell. Come noto, durante il controllo ortografico non tutte le parole sconosciute al dizionario standard sono errate; possono essere aggiunte al dizionario personalizzato. Se si rende il dizionario personalizzato parte del codice sorgente del progetto, la quality gate per l'ortografia pu\u00f2 essere formulata come segue: eseguire aspell con il dizionario standard e quello personalizzato. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/CourseOrchestra\/celesta\/blob\/271dcfc8dc3ad65ac2d1dcaa39b7fd3ea8fb5891\/Jenkinsfile#L36\">non deve<\/a><\/noindex> trovare errori di ortografia.<\/p>\n<h2>Sull'importanza di registrare la versione dell'analizzatore.<\/h2>\n<p>\nIn conclusione, \u00e8 importante notare che, qualunque sia il modo in cui implementate l'analisi nel vostro processo di consegna, la versione dell'analizzatore deve essere fissa. Se consentite un aggiornamento automatico dell'analizzatore, potrebbero emergere nuovi difetti durante la creazione di un pull request, non legati a modifiche del codice, ma al fatto che il nuovo analizzatore \u00e8 semplicemente in grado di trovare pi\u00f9 difetti, e questo romper\u00e0 il vostro processo di accettazione dei pull request. L'aggiornamento dell'analizzatore deve essere un'azione consapevole. Tuttavia, il fissare rigidamente la versione di ciascun componente della build \u00e8 in generale un requisito necessario e un tema di cui parlare separatamente.<\/p>\n<h2>Conclusioni<\/h2>\n<p><\/p>\n<ul>\n<li>L'analisi statica non trover\u00e0 bug per voi e non migliorer\u00e0 la qualit\u00e0 del vostro prodotto come risultato di un'applicazione una tantum. Solo un'applicazione costante nel processo di consegna porta effetti positivi sulla qualit\u00e0.<\/li>\n<li>La ricerca dei bug non \u00e8 affatto l'obiettivo principale dell'analisi; la stragrande maggioranza delle funzioni utili \u00e8 disponibile negli strumenti open source.<\/li>\n<li>Implementate quality gates sulla base dei risultati dell'analisi statica sin dalle prime fasi del processo di consegna, utilizzando un 'ratchet' per il codice legacy.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Link<\/h2>\n<p><\/p>\n<ol>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.amazon.com\/Continuous-Delivery-Deployment-Automation-Addison-Wesley\/dp\/0321601912\">Continuous Delivery<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=8Cx3LHNjI24\">A. Kudryavtsev: Analisi dei programmi: come capire se sei un buon programmatore<\/a><\/noindex> relazione su vari metodi di analisi del codice (non solo statico!)<\/li>\n<\/ol>\n<p>Fonte: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/436868\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u044d\u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u044e \u043c\u0435\u043d\u044f \u0441\u043f\u043e\u0434\u0432\u0438\u0433\u043b\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u043e\u0432 \u043e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0430\u043d\u0430\u043b\u0438\u0437\u0435, \u0432\u0441\u0451 \u0447\u0430\u0449\u0435 \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0449\u0438\u0445\u0441\u044f \u043d\u0430 \u0433\u043b\u0430\u0437\u0430. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u044d\u0442\u043e \u0431\u043b\u043e\u0433 PVS-studio, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u043f\u0440\u043e\u0434\u0432\u0438\u0433\u0430\u0435\u0442 \u0441\u0435\u0431\u044f \u043d\u0430 \u0425\u0430\u0431\u0440\u0435 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043e\u0431\u0437\u043e\u0440\u043e\u0432 \u043e\u0448\u0438\u0431\u043e\u043a, \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0445 \u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u043a\u043e\u0434\u043e\u043c. \u041d\u0435\u0434\u0430\u0432\u043d\u043e PVS-studio \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 Java, \u0438, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 IntelliJ IDEA, \u0447\u0435\u0439 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f, \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":24622,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-32848","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.0.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u044d\u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u044e \u043c\u0435\u043d\u044f \u0441\u043f\u043e\u0434\u0432\u0438\u0433\u043b\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u043e\u0432 \u043e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0430\u043d\u0430\u043b\u0438\u0437\u0435, \u0432\u0441\u0451 \u0447\u0430\u0449\u0435 \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0449\u0438\u0445\u0441\u044f \u043d\u0430 \u0433\u043b\u0430\u0437\u0430. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u044d\u0442\u043e \u0431\u043b\u043e\u0433 PVS-studio, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u043f\u0440\u043e\u0434\u0432\u0438\u0433\u0430\u0435\u0442 \u0441\u0435\u0431\u044f \u043d\u0430 \u0425\u0430\u0431\u0440\u0435 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043e\u0431\u0437\u043e\u0440\u043e\u0432 \u043e\u0448\u0438\u0431\u043e\u043a, \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0445 \u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u043a\u043e\u0434\u043e\u043c. \u041d\u0435\u0434\u0430\u0432\u043d\u043e PVS-studio \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 Java, \u0438, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 IntelliJ IDEA, \u0447\u0435\u0439 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f, \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435,\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/vnedryajte-staticheskij-analiz-v-protsess-a-ne-ishhite-s-ego-pomoshhyu-bagi\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.0.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"it_IT\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0412\u043d\u0435\u0434\u0440\u044f\u0439\u0442\u0435 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437 \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441, \u0430 \u043d\u0435 \u0438\u0449\u0438\u0442\u0435 \u0441 \u0435\u0433\u043e \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0431\u0430\u0433\u0438 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u044d\u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u044e \u043c\u0435\u043d\u044f \u0441\u043f\u043e\u0434\u0432\u0438\u0433\u043b\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u043e\u0432 \u043e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0430\u043d\u0430\u043b\u0438\u0437\u0435, \u0432\u0441\u0451 \u0447\u0430\u0449\u0435 \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0449\u0438\u0445\u0441\u044f \u043d\u0430 \u0433\u043b\u0430\u0437\u0430. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u044d\u0442\u043e \u0431\u043b\u043e\u0433 PVS-studio, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u043f\u0440\u043e\u0434\u0432\u0438\u0433\u0430\u0435\u0442 \u0441\u0435\u0431\u044f \u043d\u0430 \u0425\u0430\u0431\u0440\u0435 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043e\u0431\u0437\u043e\u0440\u043e\u0432 \u043e\u0448\u0438\u0431\u043e\u043a, \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0445 \u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u043a\u043e\u0434\u043e\u043c. \u041d\u0435\u0434\u0430\u0432\u043d\u043e PVS-studio \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 Java, \u0438, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 IntelliJ IDEA, \u0447\u0435\u0439 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f, \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435,\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/vnedryajte-staticheskij-analiz-v-protsess-a-ne-ishhite-s-ego-pomoshhyu-bagi\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:49:16+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:49:16+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Integra l'analisi statica nel processo, invece di cercare bug con essa | ProHoster","description":"La mia decisione di scrivere questo articolo \u00e8 stata ispirata dalla grande quantit\u00e0 di materiali sull'analisi statica, che compaiono sempre pi\u00f9 spesso. Innanzitutto, si tratta del blog PVS-studio, che promuove attivamente se stesso su Habr tramite recensioni degli errori trovati dal loro strumento in progetti open source. Recentemente, PVS-studio ha implementato il supporto per Java e, naturalmente, gli sviluppatori di IntelliJ IDEA, il cui analizzatore integrato \u00e8 ad oggi, probabilmente,","canonical_url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/vnedryajte-staticheskij-analiz-v-protsess-a-ne-ishhite-s-ego-pomoshhyu-bagi","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"it_IT","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0412\u043d\u0435\u0434\u0440\u044f\u0439\u0442\u0435 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437 \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441, \u0430 \u043d\u0435 \u0438\u0449\u0438\u0442\u0435 \u0441 \u0435\u0433\u043e \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0431\u0430\u0433\u0438 | ProHoster","og:description":"\u041d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u044d\u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u044e \u043c\u0435\u043d\u044f \u0441\u043f\u043e\u0434\u0432\u0438\u0433\u043b\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u043e\u0432 \u043e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0430\u043d\u0430\u043b\u0438\u0437\u0435, \u0432\u0441\u0451 \u0447\u0430\u0449\u0435 \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0449\u0438\u0445\u0441\u044f \u043d\u0430 \u0433\u043b\u0430\u0437\u0430. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u044d\u0442\u043e \u0431\u043b\u043e\u0433 PVS-studio, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u043f\u0440\u043e\u0434\u0432\u0438\u0433\u0430\u0435\u0442 \u0441\u0435\u0431\u044f \u043d\u0430 \u0425\u0430\u0431\u0440\u0435 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043e\u0431\u0437\u043e\u0440\u043e\u0432 \u043e\u0448\u0438\u0431\u043e\u043a, \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0445 \u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u043a\u043e\u0434\u043e\u043c. \u041d\u0435\u0434\u0430\u0432\u043d\u043e PVS-studio \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 Java, \u0438, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 IntelliJ IDEA, \u0447\u0435\u0439 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f, \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435,","og:url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/vnedryajte-staticheskij-analiz-v-protsess-a-ne-ishhite-s-ego-pomoshhyu-bagi","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T18:49:16+00:00","article:modified_time":"2019-10-31T18:49:16+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"32848","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-21 12:50:20","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 02:51:27","updated":"2026-01-21 12:50:20","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/32848","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/comments?post=32848"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/32848\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media\/24622"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media?parent=32848"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/categories?post=32848"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/tags?post=32848"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}