{"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\/sv\/blog\/administrirovanie\/vnedryajte-staticheskij-analiz-v-protsess-a-ne-ishhite-s-ego-pomoshhyu-bagi","title":{"rendered":"Integrera statisk analys i processen ist\u00e4llet f\u00f6r att anv\u00e4nda den f\u00f6r att leta efter buggar","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Att skriva den h\u00e4r artikeln inspirerades av den stora m\u00e4ngden material om statisk analys som allt oftare dyker upp. F\u00f6r det f\u00f6rsta \u00e4r det <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/en\/company\/pvs-studio\/blog\/\">PVS-studio bloggen<\/a><\/noindex>, som aktivt marknadsf\u00f6r sig p\u00e5 Habr med hj\u00e4lp av recensioner av fel som hittats av deras verktyg i projekt med \u00f6ppen k\u00e4llkod. Nyligen implementerade PVS-studio <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/en\/company\/pvs-studio\/blog\/436496\/\">st\u00f6d f\u00f6r Java<\/a><\/noindex>, och sj\u00e4lvklart kunde utvecklarna av IntelliJ IDEA, vars inbyggda analysator idag \u00e4r den mest avancerade f\u00f6r Java, <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/en\/company\/JetBrains\/blog\/436278\/\">inte st\u00e5 vid sidan av<\/a><\/noindex>. <\/p>\n<p>Vid l\u00e4sningen av s\u00e5dana recensioner f\u00e5r man k\u00e4nslan av att det handlar om ett magiskt elixir: tryck p\u00e5 en knapp, och h\u00e4r \u00e4r listan \u00f6ver defekter framf\u00f6r \u00f6gonen. Det verkar som att ju mer avancerade analysatorerna blir, desto fler buggar kommer automatiskt att uppt\u00e4ckas, och produkter som skannats av dessa robotar kommer att bli allt b\u00e4ttre utan n\u00e5gra anstr\u00e4ngningar fr\u00e5n v\u00e5r sida.<\/p>\n<p>Men det finns inga magiska elixir. Jag skulle vilja prata om vad som vanligtvis inte n\u00e4mns i inl\u00e4gg som \"det h\u00e4r \u00e4r vad v\u00e5r robot kan hitta\": vad analysatorer aldrig kan g\u00f6ra, vilken deras verkliga roll och plats \u00e4r i mjukvaruleveransprocessen, och hur man implementerar dem p\u00e5 r\u00e4tt s\u00e4tt.<\/p>\n<p><img decoding=\"async\" alt=\"Integrera statisk analys i processen ist\u00e4llet f\u00f6r att anv\u00e4nda den f\u00f6r att leta efter buggar\" src=\"\/wp-content\/uploads\/2019\/05\/2a0339f10edcaed3310676ab6e2f975a.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Hraavoqik (k\u00e4lla: <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>Vad statiska analysatorer aldrig kommer att kunna<\/h2>\n<p>\nVad inneb\u00e4r det, ur ett praktiskt perspektiv, att analysera k\u00e4llkoden? Vi matar in vissa k\u00e4llfiler, och p\u00e5 kort tid (mycket kortare \u00e4n att k\u00f6ra tester) f\u00e5r vi viss information om v\u00e5rt system. En grundl\u00e4ggande och matematiskt o\u00f6verkomlig begr\u00e4nsning \u00e4r att vi p\u00e5 detta s\u00e4tt endast kan f\u00e5 en ganska sn\u00e4v klass av information.<\/p>\n<p>Det mest k\u00e4nda exemplet p\u00e5 ett problem som inte kan l\u00f6sas med statisk analys \u00e4r <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Halting_problem\">stoppproblemet<\/a><\/noindex>: detta \u00e4r en teorem som bevisar att det \u00e4r om\u00f6jligt att utveckla en allm\u00e4n algoritm som utifr\u00e5n k\u00e4llkoden till ett program kan avg\u00f6ra om det kommer att g\u00e5 i en o\u00e4ndlig loop eller avslutas inom en \u00e4ndlig tid. En utvidgning av denna teorem \u00e4r <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Rice%27s_theorem\">Rays teorem<\/a><\/noindex>, som h\u00e4vdar att f\u00f6r varje icke-trivial egenskap av ber\u00e4kningsbara funktioner \u00e4r definitionen av huruvida ett godtyckligt program ber\u00e4knar en funktion med en s\u00e5dan egenskap en algoritmiskt ol\u00f6slig uppgift. Till exempel, det \u00e4r om\u00f6jligt att skriva en analysator som, f\u00f6r vilken k\u00e4llkod som helst, avg\u00f6r om det analyserade programmet \u00e4r en implementering av en algoritm som ber\u00e4knar, l\u00e5t oss s\u00e4ga, kvadraten av ett heltal.<\/p>\n<p>D\u00e4rf\u00f6r har funktionaliteten hos statiska analysatorer o\u00f6verkomliga begr\u00e4nsningar. En statisk analysator kommer aldrig att kunna i alla fall identifiera s\u00e5dana saker som till exempel uppkomsten av \"null pointer exception\" i spr\u00e5k som till\u00e5ter null-v\u00e4rden, eller i alla fall identifiera f\u00f6rekomsten av \"attribute not found\" i spr\u00e5k med dynamisk typning. Allt som den mest avancerade statiska analysatorn kan g\u00f6ra \u00e4r att lyfta fram exceptionella fall, vars antal bland alla m\u00f6jliga problem med din k\u00e4llkod utan \u00f6verdrift \u00e4r en droppe i havet.<\/p>\n<h2>Statisk analys \u00e4r inte buggs\u00f6kning<\/h2>\n<p>\nAv det ovanst\u00e5ende framg\u00e5r slutsatsen: statisk analys \u00e4r inte ett verktyg f\u00f6r att minska antalet defekter i programmet. Jag v\u00e5gar p\u00e5st\u00e5 att vid f\u00f6rsta till\u00e4mpningen p\u00e5 ditt projekt kommer den att hitta \"intressanta\" st\u00e4llen i koden, men mycket troligt kommer den inte att hitta n\u00e5gra defekter som p\u00e5verkar din programs prestanda.<\/p>\n<p>Exempel p\u00e5 defekter som automatiskt uppt\u00e4ckts av analysatorer \u00e4r imponerande, men man b\u00f6r inte gl\u00f6mma att dessa exempel hittades genom att skanna ett stort antal omfattande kodbaser. P\u00e5 samma s\u00e4tt som hackare, som har m\u00f6jlighet att f\u00f6rs\u00f6ka n\u00e5gra enkla l\u00f6senord p\u00e5 m\u00e5nga konton, s\u00e5 sm\u00e5ningom hittar de konton som har ett enkelt l\u00f6senord.<\/p>\n<p>Betyder detta att statisk analys inte ska till\u00e4mpas? Sj\u00e4lvklart inte! Och av exakt samma anledning som man b\u00f6r kontrollera varje nytt l\u00f6senord mot en lista \u00f6ver \"enkla\" l\u00f6senord.<\/p>\n<h2>Statiska analyser \u00e4r mer \u00e4n buggs\u00f6kning<\/h2>\n<p>\nI sj\u00e4lva verket \u00e4r de praktiskt l\u00f6sbara uppgifterna som analyseras mycket bredare. Eftersom statisk analys \u00f6verlag \u00e4r vilken kontroll av koden som helst som utf\u00f6rs f\u00f6re dess k\u00f6rning. H\u00e4r \u00e4r n\u00e5gra saker man kan g\u00f6ra:<\/p>\n<ul>\n<li> Kodgranskning i vid bem\u00e4rkelse av ordet. Detta inkluderar b\u00e5de formateringskontroll och s\u00f6kning efter anv\u00e4ndning av \u00f6verfl\u00f6diga\/\u00f6verblivna parenteser, inst\u00e4llning av tr\u00f6skelv\u00e4rden f\u00f6r metrik som antal rader\/cykelmatisk komplexitet f\u00f6r metoder etc. \u2014 allt som potentiellt f\u00f6rsv\u00e5rar l\u00e4sbarheten och underh\u00e5llbarheten av koden. I Java \u00e4r ett s\u00e5dant verktyg Checkstyle, i Python \u2014 flake8. Program av denna typ kallas vanligtvis \"linters\".<\/li>\n<li>Analys kan g\u00f6ras inte bara p\u00e5 k\u00f6rbar kod. Resursfiler s\u00e5som JSON, YAML, XML, .properties kan (och b\u00f6r!) automatiskt verifieras f\u00f6r giltighet. Det \u00e4r b\u00e4ttre att uppt\u00e4cka att strukturen f\u00f6r JSON har brutits p\u00e5 grund av oj\u00e4mna citationstecken i ett tidigt skede av automatisk kontroll av Pull Request, \u00e4n vid k\u00f6rning av tester eller under k\u00f6rtid? Relevanta verktyg finns: exempelvis, <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> Kompilering (eller parsing f\u00f6r dynamiska programmeringsspr\u00e5k) \u00e4r ocks\u00e5 en form av statisk analys. Generellt kan kompilatorer ge varningar som signalerar problem med kvaliteten p\u00e5 k\u00e4llkoden, och dessa b\u00f6r inte ignoreras.<\/li>\n<li>Ibland \u00e4r kompilering inte bara kompilering av k\u00f6rbar kod. Om du till exempel har dokumentation i formatet <noindex><a rel=\"nofollow\" href=\"https:\/\/asciidoctor.org\/\">AsciiDoctor<\/a><\/noindex>, s\u00e5 kan i samband med att den omvandlas till HTML\/PDF, AsciiDoctor (<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/asciidoctor\/asciidoctor-maven-plugin\">Maven-plugin<\/a><\/noindex>) ge varningar, exempelvis om brutna interna l\u00e4nkar. Och detta \u00e4r en stark anledning att inte godk\u00e4nna en Pull Request med \u00e4ndringar i dokumentationen.<\/li>\n<li>Stavningskontroll \u00e4r ocks\u00e5 en form av statisk analys. Verktyget <noindex><a rel=\"nofollow\" href=\"http:\/\/aspell.net\/\">aspell<\/a><\/noindex> kan kontrollera stavning inte bara i dokumentation utan ocks\u00e5 i k\u00e4llkoder (kommentarer och litteraler) p\u00e5 olika programmeringsspr\u00e5k, inklusive C\/C++, Java och Python. Stavfel i anv\u00e4ndargr\u00e4nssnittet eller dokumentationen \u00e4r ocks\u00e5 en defekt!<\/li>\n<li>Konfigurationstester (om vad det \u00e4r \u2014 se <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=KaeEjsAjV6A&amp;index=30&amp;list=PLsVTVVvrKX9tuYyCtL8mASB6IOaa-kRCA&amp;t=0s\">det h\u00e4r<\/a><\/noindex> och <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=Tk_nmV-mWOA\">det h\u00e4r<\/a><\/noindex> f\u00f6redrag), \u00e4ven om de k\u00f6rs i milj\u00f6n f\u00f6r modul\u00e4ra testtyper som pytest, \u00e4r faktiskt ocks\u00e5 en typ av statisk analys, eftersom de inte k\u00f6r k\u00e4llkoden under sin k\u00f6rning.<\/li>\n<\/ul>\n<p>\nSom vi ser spelar felletande i denna lista den minst viktiga rollen, och allt annat \u00e4r tillg\u00e4ngligt genom att anv\u00e4nda gratis open source-verktyg.<\/p>\n<p>Vilka av dessa typer av statisk analys b\u00f6r anv\u00e4ndas i ditt projekt? Sj\u00e4lvklart, ju fler desto b\u00e4ttre! Det viktigaste \u00e4r att implementera det korrekt, vilket vi kommer att diskutera n\u00e4sta.<\/p>\n<h2>Leveranspipeline som en flertrinsfilter och statisk analys som dess f\u00f6rsta steg<\/h2>\n<p>\nDen klassiska metaforen f\u00f6r kontinuerlig integration \u00e4r en pipeline d\u00e4r \u00e4ndringar fl\u00f6dar \u2014 fr\u00e5n \u00e4ndring av k\u00e4llkoden till leverans i produktion. Den standardiserade sekvensen av steg i denna pipeline ser ut s\u00e5 h\u00e4r:<\/p>\n<ol>\n<li>statisk analys<\/li>\n<li>kompilering<\/li>\n<li>modultester<\/li>\n<li>integreringstester<\/li>\n<li>UI-tester<\/li>\n<li>manuell kontroll<\/li>\n<\/ol>\n<p>\n\u00c4ndringar som avvisas vid steg N i pipelinen g\u00e5r inte vidare till steg N+1.<\/p>\n<p>Varf\u00f6r just s\u00e5, och inte p\u00e5 n\u00e5got annat s\u00e4tt? I den del av pipelinen som r\u00f6r tester f\u00e5r testare l\u00e4ra sig om den v\u00e4lk\u00e4nda testpyramiden.<\/p>\n<p><img decoding=\"async\" alt=\"Integrera statisk analys i processen ist\u00e4llet f\u00f6r att anv\u00e4nda den f\u00f6r att leta efter buggar\" src=\"\/wp-content\/uploads\/2019\/05\/f155307fd4c1663800843c394098ea6f.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Testpyramiden. K\u00e4lla: <noindex><a rel=\"nofollow\" href=\"https:\/\/martinfowler.com\/bliki\/TestPyramid.html\">artikeln<\/a><\/noindex> Martin Fowler.<\/i><\/p>\n<p>I den nedre delen av denna pyramid finns tester som \u00e4r l\u00e4ttare att skriva, som k\u00f6rs snabbare och som inte tenderar att ge falska positiva resultat. D\u00e4rf\u00f6r b\u00f6r det finnas fler av dem, de b\u00f6r t\u00e4cka mer kod och k\u00f6ras f\u00f6rst. I den \u00f6vre delen av pyramiden \u00e4r det tv\u00e4rtom, varf\u00f6r antalet integreringstester och UI-tester b\u00f6r minskas till ett absolut minimum. M\u00e4nniskan i denna kedja \u00e4r den dyraste, l\u00e5ngsammaste och mest op\u00e5litliga resursen, d\u00e4rf\u00f6r befinner den sig i slutet och utf\u00f6r arbete endast om de f\u00f6reg\u00e5ende stegen inte har uppt\u00e4ckt n\u00e5gra defekter. Men samma principer g\u00e4ller \u00e4ven f\u00f6r pipeline i delar som inte direkt r\u00f6r testning!<\/p>\n<p>Jag skulle vilja f\u00f6resl\u00e5 en analogi med ett flertrins vattenfilter. P\u00e5 ing\u00e5ngen matas smutsigt vatten (\u00e4ndringar med defekter) och p\u00e5 utg\u00e5ngen b\u00f6r vi f\u00e5 rent vatten, d\u00e4r alla o\u00f6nskade f\u00f6roreningar \u00e4r borttagna.<\/p>\n<p><img decoding=\"async\" alt=\"Integrera statisk analys i processen ist\u00e4llet f\u00f6r att anv\u00e4nda den f\u00f6r att leta efter buggar\" src=\"\/wp-content\/uploads\/2019\/05\/76b5be8f13d55c16970d67e09767a045.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Flertrinsfilter. K\u00e4lla: <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>Som bekant \u00e4r reng\u00f6rande filter utformade s\u00e5 att varje f\u00f6ljande steg kan filtrera bort allt finare fraktioner av f\u00f6roreningar. I detta sammanhang inneb\u00e4r det att de grova reningsstegen har h\u00f6gre kapacitet och l\u00e4gre kostnad. I v\u00e5r analogi betyder detta att de ing\u00e5ende kvalitetsportarna har b\u00e4ttre prestanda, kr\u00e4ver mindre anstr\u00e4ngning f\u00f6r att starta och \u00e4r mindre kr\u00e4vande i anv\u00e4ndningen \u2014 och just i den sekvensen \u00e4r de organiserade. Rollen av statisk analys, som vi nu f\u00f6rst\u00e5r kan f\u00e5nga upp endast de mest grova felen \u2014 \u00e4r som ett<\/p>\n<p>Statisk analys f\u00f6rb\u00e4ttrar i sig sj\u00e4lvt inte kvaliteten p\u00e5 den slutliga produkten, precis som en grov filtrering inte g\u00f6r vattnet drickbart. \u00c4nd\u00e5 \u00e4r dess betydelse uppenbar i den \u00f6vergripande kedjan av andra element i processen. \u00c4ven om utg\u00e5ngsstegen i ett flerstegsf filter potentiellt kan f\u00e5nga upp samma saker som ing\u00e5ngsstegen \u2014 \u00e4r det tydligt vilka konsekvenser det f\u00e5r att utesluta ing\u00e5ngssteget och bara f\u00f6rlita sig p\u00e5 fina reningssteg.<\/p>\n<p>M\u00e5let med den grova filtreringen \u00e4r att avlasta efterf\u00f6ljande steg fr\u00e5n att f\u00e5nga grova defekter. Till exempel, i varje fall, b\u00f6r personen som g\u00f6r kodgranskning inte beh\u00f6va distraheras av felaktigt formaterad kod och brott mot fastst\u00e4llda kodningsnormer (som \u00f6verfl\u00f6diga parenteser eller f\u00f6r djupt n\u00e4stlade strukturer). Buggar som NPE b\u00f6r f\u00e5ngas av enhetstester, men om analysverktyget redan f\u00f6re testen p\u00e5pekar att en bugg oundvikligen kommer att intr\u00e4ffa \u2014 kommer detta att p\u00e5skynda dess r\u00e4ttelse betydligt.<\/p>\n<p>Jag antar att det nu \u00e4r klart varf\u00f6r statisk analys inte f\u00f6rb\u00e4ttrar produktens kvalitet om den till\u00e4mpas sporadiskt, och att den b\u00f6r till\u00e4mpas kontinuerligt f\u00f6r att avvisa f\u00f6r\u00e4ndringar med grova defekter. Fr\u00e5gan om huruvida anv\u00e4ndningen av statisk analysator f\u00f6rb\u00e4ttrar kvaliteten p\u00e5 din produkt \u00e4r ungef\u00e4r densamma som att fr\u00e5ga \"kommer dricksvattnet, taget fr\u00e5n en smutsig vattenk\u00e4lla, f\u00f6rb\u00e4ttras om det passerar genom en sikt?\"<\/p>\n<h2>Implementering i ett legacy-projekt<\/h2>\n<p>\nEtt viktigt praktiskt sp\u00f6rsm\u00e5l: hur implementerar man statisk analys i processen f\u00f6r kontinuerlig integration som en \"quality gate\"? N\u00e4r det g\u00e4ller automatiska tester \u00e4r allt uppenbart: det finns en upps\u00e4ttning tester, misslyckande av vilket som helst av dem \u00e4r en tillr\u00e4cklig grund f\u00f6r att anse att bygget inte har passerat quality gate. Att f\u00f6rs\u00f6ka p\u00e5 samma s\u00e4tt s\u00e4tta en gate baserat p\u00e5 resultaten av statisk analys misslyckas: p\u00e5 legacy-kod finns det alldeles f\u00f6r m\u00e5nga varningar fr\u00e5n analysen, man vill inte helt ignorera dem, men det g\u00e5r inte heller att stoppa produkten bara f\u00f6r att det finns varningar fr\u00e5n analysverktyget.<\/p>\n<p>N\u00e4r det appliceras f\u00f6r f\u00f6rsta g\u00e5ngen p\u00e5 vilket projekt som helst ger analysverktyget en enorm m\u00e4ngd varningar, d\u00e4r den absoluta majoriteten inte har n\u00e5got att g\u00f6ra med produktens korrekta funktion. Att omedelbart \u00e5tg\u00e4rda alla dessa anm\u00e4rkningar \u00e4r inte m\u00f6jligt, och m\u00e5nga av dem beh\u00f6ver inte \u00e5tg\u00e4rdas. Vi vet ju att v\u00e5r produkt fungerar i stort, \u00e4ven innan inf\u00f6randet av statisk analys!<\/p>\n<p>Som ett resultat begr\u00e4nsar m\u00e5nga sig till sporadisk anv\u00e4ndning av statisk analys, eller anv\u00e4nder den bara i informationsl\u00e4ge, d\u00e4r det bara ges en rapport fr\u00e5n analysverktyget vid bygget. Detta \u00e4r likv\u00e4rdigt med avsaknaden av n\u00e5gon analys, eftersom om vi redan har ett antal varningar s\u00e5 f\u00f6rblir det ett f\u00f6rbisett problem om det dyker upp ytterligare en (oavsett hur allvarlig) vid kod\u00e4ndring.<\/p>\n<p>F\u00f6ljande metoder f\u00f6r att inf\u00f6ra quality gates \u00e4r k\u00e4nda:<\/p>\n<ul>\n<li>Att s\u00e4tta en gr\u00e4ns f\u00f6r det totala antalet varningar eller antalet varningar delat med antalet kodrader. Detta fungerar d\u00e5ligt, eftersom en s\u00e5dan gate l\u00e4tt sl\u00e4pper igenom \u00e4ndringar med nya defekter s\u00e5 l\u00e4nge deras gr\u00e4ns inte \u00f6verskrids.<\/li>\n<li>Vid en viss tidpunkt kan alla gamla varningar i koden hanteras som ignorerade, vilket g\u00f6r att byggprocessen misslyckas vid nya varningar. Denna funktionalitet erbjuds av PVS-studio och vissa onlinetj\u00e4nster, som Codacy. Jag har inte arbetat med PVS-studio, men n\u00e4r det g\u00e4ller min erfarenhet av Codacy ligger deras st\u00f6rsta problem i att avg\u00f6ra vad som \u00e4r ett \"gammalt\" respektive \"nytt\" fel \u2013 en ganska sv\u00e5r och inte alltid korrekt fungerande algoritm, speciellt om filer har f\u00f6r\u00e4ndrats kraftigt eller f\u00e5tt nya namn. Fr\u00e5n min erfarenhet har Codacy kunnat hoppa \u00f6ver nya varningar i en pull-request samtidigt som den kan avvisa en pull request p\u00e5 grund av varningar som inte relaterar till \u00e4ndringarna i koden f\u00f6r denna PR.<\/li>\n<li>Enligt min mening \u00e4r den mest effektiva l\u00f6sningen den som beskrivs i boken <noindex><a rel=\"nofollow\" href=\"https:\/\/www.amazon.com\/Continuous-Delivery-Deployment-Automation-Addison-Wesley\/dp\/0321601912\">Kontinuerlig leverans<\/a><\/noindex> \u00bbratcheting\u00bb-metoden. Huvudid\u00e9n \u00e4r att varje version har ett antal varningar fr\u00e5n statisk analys, och endast s\u00e5dana \u00e4ndringar till\u00e5ts som inte \u00f6kar det totala antalet varningar.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Ratcheting<\/h2>\n<p>\nDet fungerar s\u00e5 h\u00e4r:<\/p>\n<ol>\n<li>I det f\u00f6rsta steget registreras antalet varningar i koden som hittas av analysatorerna i metadata om versionen. D\u00e4rmed registreras vid bygget av huvudgrenen i din repository manager inte bara \"version 7.0.2\", utan \"version 7.0.2 med 100500 Checkstyle-varningar\". Om du anv\u00e4nder en avancerad repository manager (som Artifactory) \u00e4r det enkelt att spara s\u00e5dan metadata om din version.<\/li>\n<li>Nu j\u00e4mf\u00f6r varje pull request under bygget det antal varningar som skapas med det antal som finns i den aktuella versionen. Om PR:n \u00f6kar detta antal passerar koden inte kvalitetstestet f\u00f6r statisk analys. Om antalet varningar minskar eller f\u00f6rblir of\u00f6r\u00e4ndrat \u2013 d\u00e5 passerar det.<\/li>\n<li>Vid n\u00e4sta version kommer det omr\u00e4knade antalet varningar att skrivas in i metadata f\u00f6r versionen igen.<\/li>\n<\/ol>\n<p>\nS\u00e5 sm\u00e5ningom, men stadigt (som n\u00e4r man arbetar med en sp\u00e4rr), kommer antalet varningar att str\u00e4va mot noll. Naturligtvis kan systemet manipuleras genom att inf\u00f6ra en ny varning, men genom att \u00e5tg\u00e4rda n\u00e5gon annans. Detta \u00e4r okej, eftersom det ger resultat p\u00e5 l\u00e5ng sikt: varningar \u00e5tg\u00e4rdas oftast inte en i taget, utan i en grupp av ett visst slag, och alla l\u00e4tt\u00e5tg\u00e4rdade varningar \u00e5tg\u00e4rdas ganska snabbt.<\/p>\n<p>I denna graf visas det totala antalet Checkstyle-varningar under ett halv\u00e5r av arbete med en s\u00e5dan \"sp\u00e4rr\" p\u00e5 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/CourseOrchestra\/celesta\">ett av v\u00e5ra OpenSource-projekt<\/a><\/noindex>. Antalet varningar har minskat med en ordning, och detta har skett p\u00e5 ett naturligt s\u00e4tt, parallellt med produktutvecklingen!<\/p>\n<p><img decoding=\"async\" alt=\"Integrera statisk analys i processen ist\u00e4llet f\u00f6r att anv\u00e4nda den f\u00f6r att leta efter buggar\" src=\"\/wp-content\/uploads\/2019\/05\/9529bb2fb32187057088e8d2c4203333.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nJag anv\u00e4nder en modifierad version av denna metod, d\u00e4r jag separat r\u00e4knar varningar uppdelat efter projektmoduler och analysverktyg, den genererade YAML-filen med metadata om bygget ser ungef\u00e4r ut s\u00e5 h\u00e4r:<\/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>\nI varje avancerad CI-system kan en \"sp\u00e4rr\" implementeras f\u00f6r alla statiska analysverktyg, utan att f\u00f6rlita sig p\u00e5 plugins och tredjepartsverktyg. Varje analysverktyg ger sin rapport i ett enkelt text- eller XML-format, som enkelt kan analyseras. Det \u00e5terst\u00e5r bara att ange den n\u00f6dv\u00e4ndiga logiken i CI-skriptet. Du kan se hur detta har implementerats i v\u00e5ra open source-projekt baserat p\u00e5 Jenkins och Artifactory <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/CourseOrchestra\/2bass\/blob\/dev\/Jenkinsfile\">h\u00e4r<\/a><\/noindex> eller <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/CourseOrchestra\/celesta\/blob\/dev\/Jenkinsfile\">h\u00e4r<\/a><\/noindex>. B\u00e5da exemplen beror p\u00e5 biblioteket <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/inponomarev\/ratchetlib\">ratchetlib<\/a><\/noindex>: metoden <code>countWarnings()<\/code> r\u00e4knar normalt xml-taggar i filer som genereras av Checkstyle och Spotbugs, och <code>compareWarningMaps()<\/code> implementerar just den sp\u00e4rren, och kastar ett fel om antalet varningar i n\u00e5gon av kategorierna \u00f6kar.<\/p>\n<p>En intressant implementering av \"ratchet\" \u00e4r m\u00f6jlig f\u00f6r att analysera stavningen av kommentarer, textstr\u00e4ngar och dokumentation med hj\u00e4lp av aspell. Som bekant \u00e4r inte alla ord som \u00e4r ok\u00e4nda f\u00f6r den standardordbok som anv\u00e4nds felaktiga n\u00e4r man kontrollerar stavningen; de kan l\u00e4ggas till i en anv\u00e4ndardictionary. Om man g\u00f6r anv\u00e4ndardictionaryn till en del av projektets k\u00e4llkod kan kvalitetsgr\u00e4nsen f\u00f6r stavning formuleras p\u00e5 f\u00f6ljande s\u00e4tt: att k\u00f6ra aspell med standard- och anv\u00e4ndardictionary. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/CourseOrchestra\/celesta\/blob\/271dcfc8dc3ad65ac2d1dcaa39b7fd3ea8fb5891\/Jenkinsfile#L36\">f\u00e5r inte<\/a><\/noindex> hitta n\u00e5gra stavfel.<\/p>\n<h2>Om betydelsen av att fastst\u00e4lla versionen av analyzern<\/h2>\n<p>\nAvslutningsvis \u00e4r det viktigt att notera f\u00f6ljande: oavsett hur ni implementerar analysen i er leveranspipeline, b\u00f6r versionen av analyzern alltid fastst\u00e4llas. Om analyzern till\u00e5ts uppgraderas av sig sj\u00e4lv kan nya defekter \"dyka upp\" vid byggandet av n\u00e4sta pull request, vilket inte \u00e4r relaterat till f\u00f6r\u00e4ndringar i koden, utan beror p\u00e5 att den nya analyzern helt enkelt kan hitta fler defekter \u2014 vilket kan f\u00f6rst\u00f6ra er process f\u00f6r godk\u00e4nnande av pull requests. Uppgradering av analyzern ska vara en medveten \u00e5tg\u00e4rd. I allm\u00e4nhet \u00e4r strikt fastst\u00e4llande av version f\u00f6r varje komponent i bygget ett n\u00f6dv\u00e4ndigt krav och ett \u00e4mne f\u00f6r en separat diskussion.<\/p>\n<h2>Slutsatser<\/h2>\n<p><\/p>\n<ul>\n<li>Statisk analys kommer inte att hitta n\u00e5gra buggar eller f\u00f6rb\u00e4ttra kvaliteten p\u00e5 er produkt som resultat av en eng\u00e5ngsapplikation. Den positiva effekten p\u00e5 kvaliteten ges endast genom kontinuerlig anv\u00e4ndning av den i leveransprocessen.<\/li>\n<li>Att hitta buggar \u00e4r \u00f6verhuvudtaget inte huvudsyftet med analysen; den \u00f6verv\u00e4ldigande majoriteten av de anv\u00e4ndbara funktionerna \u00e4r tillg\u00e4ngliga i opensource-verktyg.<\/li>\n<li>Implementera kvalitetsgr\u00e4nser baserat p\u00e5 resultaten av statisk analys redan i det f\u00f6rsta steget av leveranspipen, anv\u00e4ndande \"ratchet\" f\u00f6r legacy-kod.<\/li>\n<\/ul>\n<p><\/p>\n<h2>L\u00e4nkar<\/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\">Kontinuerlig leverans<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=8Cx3LHNjI24\">A. Kudryavtsev: Programanalys: hur man f\u00f6rst\u00e5r att man \u00e4r en bra programmerare<\/a><\/noindex> en presentation om olika kodanalysmetoder (inte bara statisk!)<\/li>\n<\/ol>\n<p>K\u00e4lla: <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.4 - 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.\" \/>\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\/sv\/blog\/administrirovanie\/vnedryajte-staticheskij-analiz-v-protsess-a-ne-ishhite-s-ego-pomoshhyu-bagi\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"sv_SE\" \/>\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.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/sv\/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\udd47Implementera statisk analys i processen ist\u00e4llet f\u00f6r att bara leta efter buggar med den | ProHoster","description":"Att skriva denna artikel inspirerades av det stora antalet material om statisk analys som allt oftare dyker upp.","canonical_url":"https:\/\/prohoster.info\/sv\/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":"sv_SE","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.","og:url":"https:\/\/prohoster.info\/sv\/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\/sv\/wp-json\/wp\/v2\/posts\/32848","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/comments?post=32848"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts\/32848\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media\/24622"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media?parent=32848"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/categories?post=32848"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/tags?post=32848"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}