{"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\/pt\/blog\/administrirovanie\/vnedryajte-staticheskij-analiz-v-protsess-a-ne-ishhite-s-ego-pomoshhyu-bagi","title":{"rendered":"Implemente a an\u00e1lise est\u00e1tica no processo, em vez de us\u00e1-la para encontrar falhas.","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>A motiva\u00e7\u00e3o para escrever este artigo foram os muitos materiais sobre an\u00e1lise est\u00e1tica que t\u00eam aparecido cada vez mais. Em primeiro lugar, este \u00e9 o <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/en\/company\/pvs-studio\/blog\/\">blog PVS-studio<\/a><\/noindex>, que se promove ativamente no Habr por meio de an\u00e1lises de erros encontrados por sua ferramenta em projetos de c\u00f3digo aberto. Recentemente, a PVS-studio implementou <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/en\/company\/pvs-studio\/blog\/436496\/\">suporte a Java<\/a><\/noindex>, e, claro, os desenvolvedores do IntelliJ IDEA, cujo analisador integrado \u00e9, atualmente, provavelmente o mais avan\u00e7ado para Java, <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/en\/company\/JetBrains\/blog\/436278\/\">n\u00e3o poderiam ficar de fora<\/a><\/noindex>. <\/p>\n<p>Ao ler tais an\u00e1lises, surge a sensa\u00e7\u00e3o de que se trata de uma po\u00e7\u00e3o m\u00e1gica: pressione um bot\u00e3o e l\u00e1 est\u00e1 \u2014 uma lista de defeitos diante de voc\u00ea. Parece que, \u00e0 medida que os analisadores melhoram, mais e mais erros ser\u00e3o automaticamente detectados, e os produtos, analisados por esses rob\u00f4s, se tornar\u00e3o cada vez melhores, sem qualquer esfor\u00e7o da nossa parte.<\/p>\n<p>Mas po\u00e7\u00f5es m\u00e1gicas n\u00e3o existem. Eu gostaria de falar sobre o que geralmente n\u00e3o \u00e9 mencionado em postagens como \"veja o que nosso rob\u00f4 pode encontrar\": o que os analisadores n\u00e3o conseguem fazer, qual \u00e9 o seu verdadeiro papel e lugar no processo de entrega de software, e como implement\u00e1-los corretamente.<\/p>\n<p><img decoding=\"async\" alt=\"Implemente a an\u00e1lise est\u00e1tica no processo, em vez de us\u00e1-la para encontrar falhas.\" src=\"\/wp-content\/uploads\/2019\/05\/2a0339f10edcaed3310676ab6e2f975a.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Rel\u00e9 (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>O que os analisadores est\u00e1ticos nunca poder\u00e3o fazer<\/h2>\n<p>\nO que \u00e9, do ponto de vista pr\u00e1tico, a an\u00e1lise de c\u00f3digo-fonte? N\u00f3s fornecemos alguns c\u00f3digos-fonte, e em um curto espa\u00e7o de tempo (muito mais curto do que a execu\u00e7\u00e3o de testes) obtemos algumas informa\u00e7\u00f5es sobre o nosso sistema. A limita\u00e7\u00e3o fundamental e matematicamente insuper\u00e1vel \u00e9 que, dessa forma, podemos obter apenas uma classe bastante restrita de informa\u00e7\u00f5es.<\/p>\n<p>O exemplo mais famoso de um problema que n\u00e3o pode ser resolvido por meio de an\u00e1lise est\u00e1tica \u00e9 a <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Halting_problem\">problema da parada<\/a><\/noindex>: \u00e9 um teorema que demonstra que n\u00e3o \u00e9 poss\u00edvel desenvolver um algoritmo geral que, dado o c\u00f3digo-fonte de um programa, determine se ele ficar\u00e1 em loop ou se terminar\u00e1 em um tempo finito. Uma extens\u00e3o desse teorema \u00e9 <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Rice%27s_theorem\">teorema de Rice<\/a><\/noindex>, afirmando que, para qualquer propriedade n\u00e3o trivial de fun\u00e7\u00f5es comput\u00e1veis, a defini\u00e7\u00e3o de se um programa arbitr\u00e1rio calcula uma fun\u00e7\u00e3o com essa propriedade \u00e9 um problema algor\u00edtmicamente indecid\u00edvel. Por exemplo, \u00e9 imposs\u00edvel escrever um analisador que, a partir de qualquer c\u00f3digo-fonte, determine se o programa analisado \u00e9 uma implementa\u00e7\u00e3o de um algoritmo que calcula, digamos, o quadrado de um n\u00famero inteiro.<\/p>\n<p>Assim, a funcionalidade dos analisadores est\u00e1ticos tem limita\u00e7\u00f5es intranspon\u00edveis. Um analisador est\u00e1tico nunca conseguir\u00e1, em todos os casos, determinar coisas como, por exemplo, a ocorr\u00eancia de uma \u00abexce\u00e7\u00e3o de ponteiro nulo\u00bb em linguagens que permitem o valor nulo, ou em todos os casos determinar a ocorr\u00eancia de \u00abatributo n\u00e3o encontrado\u00bb em linguagens com tipagem din\u00e2mica. Tudo o que o analisador est\u00e1tico mais avan\u00e7ado pode fazer \u00e9 destacar casos particulares, cuja quantidade entre todos os poss\u00edveis problemas com seu c\u00f3digo-fonte \u00e9, sem exagero, uma gota no oceano.<\/p>\n<h2>An\u00e1lise est\u00e1tica n\u00e3o \u00e9 busca de bugs<\/h2>\n<p>\nDo exposto, segue a conclus\u00e3o: an\u00e1lise est\u00e1tica n\u00e3o \u00e9 um meio de reduzir a quantidade de defeitos em um programa. Arrisco-me a afirmar: ao ser aplicado pela primeira vez em seu projeto, ele encontrar\u00e1 no c\u00f3digo 'pontos interessantes', mas, provavelmente, n\u00e3o encontrar\u00e1 nenhum defeito que afete a qualidade do funcionamento do seu programa.<\/p>\n<p>Os exemplos de defeitos encontrados automaticamente por analisadores s\u00e3o impressionantes, mas n\u00e3o se deve esquecer que esses exemplos foram encontrados por meio da varredura de um grande n\u00famero de grandes bases de c\u00f3digo. Da mesma forma, hackers que t\u00eam a capacidade de testar v\u00e1rias senhas simples em uma grande quantidade de contas eventualmente encontrar\u00e3o aquelas contas que t\u00eam senhas simples.<\/p>\n<p>Isso significa que a an\u00e1lise est\u00e1tica n\u00e3o deve ser aplicada? Claro que n\u00e3o! E exatamente pela mesma raz\u00e3o pela qual vale a pena verificar cada nova senha para ver se ela est\u00e1 na lista de 'senhas simples'.<\/p>\n<h2>An\u00e1lise est\u00e1tica \u00e9 mais do que busca de bugs<\/h2>\n<p>\nNa verdade, as tarefas que podem ser resolvidas pela an\u00e1lise s\u00e3o muito mais amplas. Afinal, no geral, a an\u00e1lise est\u00e1tica \u00e9 qualquer verifica\u00e7\u00e3o de c\u00f3digo-fonte realizada antes de sua execu\u00e7\u00e3o. Aqui est\u00e3o algumas coisas que podem ser feitas:<\/p>\n<ul>\n<li> A verifica\u00e7\u00e3o do estilo de codifica\u00e7\u00e3o no sentido amplo da palavra. Isso inclui tanto a verifica\u00e7\u00e3o de formata\u00e7\u00e3o quanto a busca por uso de par\u00eanteses desnecess\u00e1rios, a configura\u00e7\u00e3o de limites para m\u00e9tricas como o n\u00famero de linhas \/ a complexidade ciclom\u00e1tica de um m\u00e9todo etc. \u2014 tudo o que pode potencialmente dificultar a legibilidade e a manuten\u00e7\u00e3o do c\u00f3digo. Em Java, uma ferramenta desse tipo \u00e9 o Checkstyle, em Python, o flake8. Programas dessa classe s\u00e3o geralmente chamados de 'linters'.<\/li>\n<li>A an\u00e1lise pode ser aplicada n\u00e3o apenas ao c\u00f3digo execut\u00e1vel. Arquivos de recursos, como JSON, YAML, XML, .properties podem (e devem!) ser automaticamente verificados quanto \u00e0 validade. Afinal, \u00e9 melhor descobrir que a estrutura JSON foi comprometida devido a algumas aspas n\u00e3o pareadas em uma etapa inicial da verifica\u00e7\u00e3o autom\u00e1tica do Pull Request do que durante a execu\u00e7\u00e3o dos testes ou em tempo de execu\u00e7\u00e3o? Existem ferramentas apropriadas, como, por exemplo, <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> A compila\u00e7\u00e3o (ou parsing para linguagens de programa\u00e7\u00e3o din\u00e2micas) tamb\u00e9m \u00e9 um tipo de an\u00e1lise est\u00e1tica. Normalmente, compiladores s\u00e3o capazes de emitir avisos que sinalizam problemas com a qualidade do c\u00f3digo-fonte, e estes n\u00e3o devem ser ignorados.<\/li>\n<li>\u00c0s vezes, a compila\u00e7\u00e3o n\u00e3o se limita apenas \u00e0 compila\u00e7\u00e3o do c\u00f3digo execut\u00e1vel. Por exemplo, se voc\u00ea tiver documenta\u00e7\u00e3o em formato <noindex><a rel=\"nofollow\" href=\"https:\/\/asciidoctor.org\/\">AsciiDoctor<\/a><\/noindex>, no momento em que ela \u00e9 convertida para HTML\/PDF, o processador AsciiDoctor (<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/asciidoctor\/asciidoctor-maven-plugin\">Maven plugin<\/a><\/noindex>) pode emitir avisos, por exemplo, sobre links internos quebrados. E isso \u00e9 uma raz\u00e3o significativa para n\u00e3o aceitar um Pull Request com altera\u00e7\u00f5es na documenta\u00e7\u00e3o.<\/li>\n<li>A verifica\u00e7\u00e3o ortogr\u00e1fica tamb\u00e9m \u00e9 um tipo de an\u00e1lise est\u00e1tica. A ferramenta <noindex><a rel=\"nofollow\" href=\"http:\/\/aspell.net\/\">aspell<\/a><\/noindex> pode verificar a ortografia n\u00e3o apenas em documenta\u00e7\u00e3o, mas tamb\u00e9m em c\u00f3digos fonte de programas (coment\u00e1rios e literais) em v\u00e1rias linguagens de programa\u00e7\u00e3o, incluindo C\/C++, Java e Python. Um erro de ortografia na interface do usu\u00e1rio ou na documenta\u00e7\u00e3o tamb\u00e9m \u00e9 um defeito!<\/li>\n<li>Os testes de configura\u00e7\u00e3o (sobre o que isso \u00e9 \u2014 veja <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=KaeEjsAjV6A&amp;index=30&amp;list=PLsVTVVvrKX9tuYyCtL8mASB6IOaa-kRCA&amp;t=0s\">este<\/a><\/noindex> e <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=Tk_nmV-mWOA\">este<\/a><\/noindex> relat\u00f3rios), embora sejam executados em ambientes de teste modular como pytest, na verdade tamb\u00e9m s\u00e3o uma forma de an\u00e1lise est\u00e1tica, pois n\u00e3o executam os c\u00f3digos-fonte durante sua execu\u00e7\u00e3o.<\/li>\n<\/ul>\n<p>\nComo vemos, a busca por bugs nessa lista desempenha o papel menos importante, enquanto tudo o que \u00e9 necess\u00e1rio est\u00e1 dispon\u00edvel atrav\u00e9s do uso de ferramentas open source gratuitas.<\/p>\n<p>Quais desses tipos de an\u00e1lise est\u00e1tica devem ser aplicados em seu projeto? Claro, todos eles \u2014 quanto mais, melhor! O importante \u00e9 implement\u00e1-los corretamente, sobre o que falaremos a seguir.<\/p>\n<h2>O pipeline de entrega como um filtro em v\u00e1rias etapas e a an\u00e1lise est\u00e1tica como seu primeiro est\u00e1gio<\/h2>\n<p>\nA met\u00e1fora cl\u00e1ssica de integra\u00e7\u00e3o cont\u00ednua \u00e9 um pipeline, pelo qual as mudan\u00e7as fluem \u2014 desde a altera\u00e7\u00e3o do c\u00f3digo fonte at\u00e9 a entrega em produ\u00e7\u00e3o. A sequ\u00eancia padr\u00e3o de etapas deste pipeline \u00e9 a seguinte:<\/p>\n<ol>\n<li>an\u00e1lise est\u00e1tica<\/li>\n<li>compila\u00e7\u00e3o<\/li>\n<li>testes de unidade<\/li>\n<li>testes de integra\u00e7\u00e3o<\/li>\n<li>testes de interface do usu\u00e1rio<\/li>\n<li>verifica\u00e7\u00e3o manual<\/li>\n<\/ol>\n<p>\nMudan\u00e7as rejeitadas na etapa N do pipeline n\u00e3o s\u00e3o transferidas para a etapa N+1.<\/p>\n<p>Por que exatamente assim e n\u00e3o de outra forma? Na parte do pipeline que diz respeito aos testes, os testadores conhecem bem a famosa pir\u00e2mide de testes.<\/p>\n<p><img decoding=\"async\" alt=\"Implemente a an\u00e1lise est\u00e1tica no processo, em vez de us\u00e1-la para encontrar falhas.\" src=\"\/wp-content\/uploads\/2019\/05\/f155307fd4c1663800843c394098ea6f.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Pir\u00e2mide de testes. Fonte: <noindex><a rel=\"nofollow\" href=\"https:\/\/martinfowler.com\/bliki\/TestPyramid.html\">artigo<\/a><\/noindex> Martin Fowler.<\/i><\/p>\n<p>Na parte inferior dessa pir\u00e2mide est\u00e3o os testes que s\u00e3o mais f\u00e1ceis de escrever, que s\u00e3o executados mais rapidamente e n\u00e3o tendem a gerar falsos positivos. Portanto, deve haver mais deles, cobrindo mais c\u00f3digo e sendo executados primeiro. Na parte superior da pir\u00e2mide, a situa\u00e7\u00e3o \u00e9 exatamente o oposto, por isso o n\u00famero de testes de integra\u00e7\u00e3o e UI deve ser reduzido ao m\u00ednimo necess\u00e1rio. A pessoa nessa cadeia \u00e9 o recurso mais caro, lento e menos confi\u00e1vel, portanto, ela est\u00e1 na extremidade e realiza seu trabalho apenas se as etapas anteriores n\u00e3o detectarem nenhum defeito. No entanto, o mesmo princ\u00edpio se aplica ao pipeline nas partes que n\u00e3o est\u00e3o diretamente relacionadas aos testes!<\/p>\n<p>Eu gostaria de propor uma analogia com um sistema de filtragem de \u00e1gua em v\u00e1rias etapas. \u00c1gua suja (mudan\u00e7as com defeitos) entra, e devemos obter \u00e1gua limpa na sa\u00edda, com todas as impurezas indesejadas filtradas.<\/p>\n<p><img decoding=\"async\" alt=\"Implemente a an\u00e1lise est\u00e1tica no processo, em vez de us\u00e1-la para encontrar falhas.\" src=\"\/wp-content\/uploads\/2019\/05\/76b5be8f13d55c16970d67e09767a045.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Filtro em v\u00e1rias etapas. 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>Como \u00e9 sabido, os filtros de limpeza s\u00e3o projetados de modo que cada cascata subsequente possa eliminar fra\u00e7\u00f5es cada vez menores de polui\u00e7\u00e3o. Neste contexto, as cascatas de limpeza mais grossa t\u00eam uma maior capacidade de passagem e um custo menor. Em nossa analogia, isso significa que os quality gates de entrada t\u00eam um desempenho melhor, requerem menos esfor\u00e7o para serem acionados e s\u00e3o, por si mesmos, mais simples de operar \u2014 e justamente nessa sequ\u00eancia est\u00e3o organizados. O papel da an\u00e1lise est\u00e1tica, que agora entendemos ser capaz de filtrar apenas os defeitos mais grosseiros \u2014 \u00e9 o papel de uma grelha de<\/p>\n<p>O que sabemos \u00e9 que a an\u00e1lise est\u00e1tica, por si s\u00f3, n\u00e3o melhora a qualidade do produto final, assim como a grelha n\u00e3o torna a \u00e1gua pot\u00e1vel. No entanto, a sua import\u00e2ncia \u00e9 evidente quando combinada com outros elementos da linha de produ\u00e7\u00e3o. Embora, em um filtro em m\u00faltiplas cascatas, as cascatas de sa\u00edda possam potencialmente capturar o mesmo que as de entrada \u2014 \u00e9 claro quais ser\u00e3o as consequ\u00eancias de tentar depender apenas das cascatas de filtragem fina, sem as cascatas de entrada.<\/p>\n<p>O objetivo da grelha \u00e9 aliviar as cascatas subsequentes de capturarem defeitos realmente grosseiros. Por exemplo, pelo menos o indiv\u00edduo que realiza a revis\u00e3o de c\u00f3digo n\u00e3o deve ser distra\u00eddo por c\u00f3digo mal formatado e viola\u00e7\u00f5es das normas de codifica\u00e7\u00e3o estabelecidas (como par\u00eanteses desnecess\u00e1rios ou ramifica\u00e7\u00f5es muito profundamente aninhadas). Bugs como o NPE devem ser identificados por testes unit\u00e1rios, mas se antes do teste o analisador nos informa que um bug ocorrer\u00e1 inevitavelmente \u2014 isso acelerar\u00e1 significativamente sua corre\u00e7\u00e3o.<\/p>\n<p>Acredito que agora est\u00e1 claro por que a an\u00e1lise est\u00e1tica n\u00e3o melhora a qualidade do produto quando aplicada de forma espor\u00e1dica, e deve ser utilizada regularmente para filtrar mudan\u00e7as com defeitos grosseiros. A quest\u00e3o sobre se o uso de um analisador est\u00e1tico melhorar\u00e1 a qualidade do seu produto \u00e9 aproximadamente equivalente \u00e0 pergunta: \"Asqualidades da \u00e1gua pot\u00e1vel provenientes de um corpo d'\u00e1gua sujo melhorar\u00e3o se forem passadas por uma peneira?\"<\/p>\n<h2>Implementa\u00e7\u00e3o em um projeto legado<\/h2>\n<p>\nUma quest\u00e3o pr\u00e1tica importante: como implementar a an\u00e1lise est\u00e1tica no processo de integra\u00e7\u00e3o cont\u00ednua como um \"quality gate\"? No caso de testes autom\u00e1ticos, tudo \u00e9 claro: existe um conjunto de testes, e a falha em qualquer um deles \u00e9 motivo suficiente para considerar que a compila\u00e7\u00e3o n\u00e3o passou pelo quality gate. Tentar estabelecer um gate com base nos resultados da an\u00e1lise est\u00e1tica falha: no c\u00f3digo legado, h\u00e1 muitas advert\u00eancias de an\u00e1lise, n\u00e3o queremos ignor\u00e1-las completamente, mas tamb\u00e9m n\u00e3o \u00e9 poss\u00edvel interromper a entrega do produto apenas porque existem advert\u00eancias do analisador.<\/p>\n<p>Quando aplicado pela primeira vez em qualquer projeto, o analisador gera uma grande quantidade de advert\u00eancias, a maioria das quais n\u00e3o se relaciona com o funcionamento correto do produto. Corrigir todos esses pontos imediatamente n\u00e3o \u00e9 vi\u00e1vel, e muitos nem precisam ser corrigidos. Afinal, sabemos que nosso produto, de maneira geral, funciona, mesmo antes da implementa\u00e7\u00e3o da an\u00e1lise est\u00e1tica!<\/p>\n<p>Como resultado, muitos se limitam ao uso espor\u00e1dico da an\u00e1lise est\u00e1tica ou a utilizam apenas em modo informativo, quando um relat\u00f3rio do analisador \u00e9 simplesmente gerado durante a compila\u00e7\u00e3o. Isso \u00e9 equivalente \u00e0 aus\u00eancia de qualquer an\u00e1lise, pois se j\u00e1 temos uma s\u00e9rie de advert\u00eancias, a ocorr\u00eancia de mais uma (por mais s\u00e9ria que seja) ao alterar o c\u00f3digo passa despercebida.<\/p>\n<p>Os seguintes m\u00e9todos de implementa\u00e7\u00e3o de quality gates s\u00e3o conhecidos:<\/p>\n<ul>\n<li>Definir um limite para o n\u00famero total de advert\u00eancias ou para o n\u00famero de advert\u00eancias dividido pelo n\u00famero de linhas de c\u00f3digo. Isso funciona mal, pois esse gate deixa passar mudan\u00e7as com novos defeitos enquanto seu limite n\u00e3o for excedido.<\/li>\n<li>A fix for all old warnings in the code at a specific moment as ignored, and a refusal to compile when new warnings arise. This functionality is provided by PVS-studio and some online resources, such as Codacy. I haven't worked with PVS-studio; regarding my experience with Codacy, their main issue is that determining what is an 'old' versus a 'new' error is quite complex and doesn't always function correctly, especially when files are heavily modified or renamed. In my memory, Codacy has been known to miss new warnings in pull requests while also blocking pull requests due to warnings unrelated to the changes in that PR.<\/li>\n<li>In my view, the most effective solution is described in the book <noindex><a rel=\"nofollow\" href=\"https:\/\/www.amazon.com\/Continuous-Delivery-Deployment-Automation-Addison-Wesley\/dp\/0321601912\">Continuous Delivery<\/a><\/noindex> the 'ratcheting method'. The main idea is that a property of each release is the number of static analysis warnings, and only changes that do not increase the total number of warnings are permitted.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Ratcheting<\/h2>\n<p>\nIt works like this:<\/p>\n<ol>\n<li>At the initial stage, metadata is recorded about the release regarding the number of warnings in the code found by analyzers. Thus, when the main branch is built, your repository manager records not just 'release 7.0.2,' but 'release 7.0.2, containing 100,500 Checkstyle warnings.' If you are using an advanced repository manager (such as Artifactory), saving such metadata about your release is easy.<\/li>\n<li>Now, each pull request compares the number of resulting warnings upon compilation with the number present in the current release. If the PR results in an increase in this number, the code does not pass the quality gate for static analysis. If the number of warnings decreases or remains unchanged, it passes.<\/li>\n<li>In the next release, the recalculated number of warnings will again be recorded in the release's metadata.<\/li>\n<\/ol>\n<p>\nAssim, lentamente, mas de forma constante (como funciona um mecanismo de ratchet), o n\u00famero de avisos tende a zero. Claro, \u00e9 poss\u00edvel enganar o sistema, inserindo um novo aviso enquanto corrige outro. Isso \u00e9 normal, pois a longo prazo resulta em efic\u00e1cia: os avisos geralmente s\u00e3o corrigidos n\u00e3o um a um, mas em grupos de um determinado tipo, e todos os avisos facilmente remov\u00edveis s\u00e3o eliminados rapidamente.<\/p>\n<p>Este gr\u00e1fico mostra o total de avisos do Checkstyle acumulados ao longo de seis meses de opera\u00e7\u00e3o de tal \"mecanismo de ratchet\" em <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/CourseOrchestra\/celesta\">um de nossos projetos OpenSource.<\/a><\/noindex>O n\u00famero de avisos foi reduzido drasticamente, e isso ocorreu de forma natural, paralelamente ao desenvolvimento do produto!<\/p>\n<p><img decoding=\"async\" alt=\"Implemente a an\u00e1lise est\u00e1tica no processo, em vez de us\u00e1-la para encontrar falhas.\" src=\"\/wp-content\/uploads\/2019\/05\/9529bb2fb32187057088e8d2c4203333.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEu aplico uma vers\u00e3o modificada desse m\u00e9todo, contando separadamente os avisos por m\u00f3dulos do projeto e pelas ferramentas de an\u00e1lise. O arquivo YAML gerado com metadados da compila\u00e7\u00e3o se parece aproximadamente com isto:<\/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>\nEm qualquer sistema CI avan\u00e7ado, o \"mecanismo de ratchet\" pode ser implementado para qualquer ferramenta de an\u00e1lise est\u00e1tica, sem depender de plugins e ferramentas de terceiros. Cada um dos analisadores gera seu relat\u00f3rio em formato de texto simples ou XML, f\u00e1cil de analisar. Basta escrever a l\u00f3gica necess\u00e1ria no script CI. \u00c9 poss\u00edvel verificar como isso foi implementado em nossos projetos de c\u00f3digo aberto baseados em Jenkins e Artifactory. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/CourseOrchestra\/2bass\/blob\/dev\/Jenkinsfile\">aqui<\/a><\/noindex> ou <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/CourseOrchestra\/celesta\/blob\/dev\/Jenkinsfile\">aqui<\/a><\/noindex>Ambos os exemplos dependem da biblioteca <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/inponomarev\/ratchetlib\">ratchetlib<\/a><\/noindex>: o m\u00e9todo <code>countWarnings()<\/code> conta as tags xml nos arquivos gerados pelo Checkstyle e Spotbugs, enquanto que <code>compareWarningMaps()<\/code> implementa o verdadeiro mecanismo de ratchet, lan\u00e7ando um erro caso o n\u00famero de avisos em qualquer uma das categorias aumente.<\/p>\n<p>Uma abordagem interessante para a implementa\u00e7\u00e3o de um \"ratchet\" \u00e9 analisar a ortografia de coment\u00e1rios, literais de texto e documenta\u00e7\u00e3o com o uso do aspell. Como \u00e9 sabido, na verifica\u00e7\u00e3o ortogr\u00e1fica, nem todas as palavras desconhecidas para o dicion\u00e1rio padr\u00e3o s\u00e3o consideradas erradas, pois podem ser adicionadas ao dicion\u00e1rio do usu\u00e1rio. Se o dicion\u00e1rio do usu\u00e1rio for parte do c\u00f3digo-fonte do projeto, ent\u00e3o o quality gate para ortografia pode ser formulado da seguinte maneira: executar o aspell com o dicion\u00e1rio padr\u00e3o e o dicion\u00e1rio do usu\u00e1rio. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/CourseOrchestra\/celesta\/blob\/271dcfc8dc3ad65ac2d1dcaa39b7fd3ea8fb5891\/Jenkinsfile#L36\">n\u00e3o deve<\/a><\/noindex> encontrar erros de ortografia.<\/p>\n<h2>Sobre a import\u00e2ncia de fixar a vers\u00e3o do analisador<\/h2>\n<p>\nEm conclus\u00e3o, \u00e9 importante notar o seguinte: independentemente da forma como voc\u00ea implementar a an\u00e1lise em seu pipeline de entrega, a vers\u00e3o do analisador deve ser fixada. Se permitir uma atualiza\u00e7\u00e3o espont\u00e2nea do analisador, novos defeitos podem \"surgir\" ao compilar um pull request, que n\u00e3o est\u00e3o relacionados a altera\u00e7\u00f5es no c\u00f3digo, mas ao fato de que o novo analisador \u00e9 capaz de detectar mais defeitos \u2014 e isso poder\u00e1 comprometer seu processo de aceita\u00e7\u00e3o de pull requests. A atualiza\u00e7\u00e3o do analisador deve ser uma a\u00e7\u00e3o consciente. No entanto, a fixa\u00e7\u00e3o rigorosa da vers\u00e3o de cada componente da compila\u00e7\u00e3o \u00e9 uma exig\u00eancia geral necess\u00e1ria e um tema para uma conversa separada.<\/p>\n<h2>Como resultado, obtemos um servi\u00e7o de \"monitoramento como servi\u00e7o\", automatizado na linha de produ\u00e7\u00e3o de integra\u00e7\u00e3o cont\u00ednua. O desenvolvedor ou testador precisa apenas definir a lista de m\u00e9tricas em um arquivo JSON, e tudo o mais acontece automaticamente. Obtemos um controle de qualidade transparente dos lan\u00e7amentos: todas as notifica\u00e7\u00f5es sobre desempenho, consumo de recursos ou regress\u00f5es arquitet\u00f4nicas.<\/h2>\n<p><\/p>\n<ul>\n<li>A an\u00e1lise est\u00e1tica n\u00e3o encontrar\u00e1 bugs nem melhorar\u00e1 a qualidade do seu produto como resultado de uma \u00fanica aplica\u00e7\u00e3o. O efeito positivo na qualidade s\u00f3 aparece com a aplica\u00e7\u00e3o cont\u00ednua durante o processo de entrega.<\/li>\n<li>A busca por bugs n\u00e3o \u00e9, de fato, a principal fun\u00e7\u00e3o da an\u00e1lise; a esmagadora maioria das fun\u00e7\u00f5es \u00fateis est\u00e1 dispon\u00edvel em ferramentas de c\u00f3digo aberto.<\/li>\n<li>Implemente quality gates com base nos resultados da an\u00e1lise est\u00e1tica na primeira etapa do pipeline de entrega, utilizando o \"ratchet\" para c\u00f3digo legado.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Links<\/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: An\u00e1lise de Programas: Como Saber Se Voc\u00ea \u00e9 um Bom Programador<\/a><\/noindex> palestra sobre diferentes m\u00e9todos de an\u00e1lise de c\u00f3digo (n\u00e3o apenas est\u00e1tica!)<\/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.3 - 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\/pt\/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.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"pt_PT\" \/>\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\/pt\/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\udd47Implemente a an\u00e1lise est\u00e1tica no processo, n\u00e3o procure bugs com ela | ProHoster","description":"A grande quantidade de material sobre an\u00e1lise est\u00e1tica, que tem aparecido com frequ\u00eancia, me motivou a escrever este artigo.","canonical_url":"https:\/\/prohoster.info\/pt\/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":"pt_PT","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\/pt\/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\/pt\/wp-json\/wp\/v2\/posts\/32848","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/comments?post=32848"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/32848\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media\/24622"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media?parent=32848"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/categories?post=32848"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/tags?post=32848"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}