[{"data":1,"prerenderedAt":3840},["ShallowReactive",2],{"/fr-fr/blog/refactor-code-into-modern-languages-with-ai-powered-gitlab-duo":3,"navigation-fr-fr":3058,"banner-fr-fr":3493,"footer-fr-fr":3501,"blog-post-authors-fr-fr-Michael Friedrich":3739,"blog-related-posts-fr-fr-refactor-code-into-modern-languages-with-ai-powered-gitlab-duo":3754,"blog-promotions-fr-fr":3778,"next-steps-fr-fr":3831},{"id":4,"title":5,"authors":6,"body":8,"category":3037,"date":3038,"description":3039,"extension":3040,"externalUrl":3041,"faq":3041,"featured":3042,"heroImage":3043,"meta":3044,"navigation":222,"path":3045,"seo":3046,"slug":3050,"stem":3051,"tags":3052,"template":3056,"updatedDate":3041,"__hash__":3057},"blogPosts/fr-fr/blog/refactor-code-into-modern-languages-with-ai-powered-gitlab-duo.md","Comment réusiner le code dans des langages modernes grâce à GitLab Duo alimenté par l'IA ",[7],"Michael Friedrich",{"type":9,"value":10,"toc":3020},"minimark",[11,40,43,139,143,146,150,153,156,932,935,945,952,975,978,991,999,1002,1005,1008,1014,1457,1489,1509,1518,1522,1531,1542,1545,1745,1751,1757,1760,1763,1772,1781,1783,1923,1929,1935,1942,1945,1954,1957,1985,1991,1997,2000,2009,2015,2024,2031,2059,2068,2074,2077,2080,2083,2092,2095,2517,2537,2548,2554,2566,2572,2575,2578,2581,2587,2851,2854,2870,2876,2898,2904,2907,2910,2913,2919,2922,2925,2931,2946,2952,2955,2978,2981,3004,3007,3016],[12,13,14,15,21,22,27,28,33,34,39],"p",{},"S'il vous incombe de moderniser le code base ou le framework en passant à un nouveau langage de programmation, ou si vous avez besoin d'en savoir plus sur les nouvelles fonctionnalités de ce langage, ",[16,17,20],"a",{"href":18,"rel":19},"https://about.gitlab.com/gitlab-duo-agent-platform/",[],"GitLab Duo"," alimenté par l'IA peut vous prêter main forte. Apprenez à aborder les défis posés par le réusinage du code en adoptant de bonnes pratiques grâce à des exemples tirés des 20 dernières années de ma carrière de codeur.\nLes prompts et les exemples de cet article sont illustrés dans différents IDE : VS Code et JetBrains (IntelliJ IDEA, PyCharm et CLion), sur lesquels sont installés les ",[16,23,26],{"href":24,"rel":25},"https://docs.gitlab.com/user/project/repository/code_suggestions/supported_extensions/",[],"extensions/plugins de GitLab Duo",". L'environnement de développement utilise GitLab.com, y compris les mises à jour vers le grand modèle de langage (LLM) Claude 3.5 d'Anthropic pour les ",[16,29,32],{"href":30,"rel":31},"https://docs.gitlab.com/user/gitlab_duo/#code-suggestions",[],"suggestions de code"," de GitLab Duo et ",[16,35,38],{"href":36,"rel":37},"https://docs.gitlab.com/user/gitlab_duo/#gitlab-duo-chat",[],"GitLab Chat",". Pour faire bref : on gagne en puissance et en efficacité.",[12,41,42],{},"Vous pouvez lire l'article dans son intégralité ou accéder directement à une section spécifique. Le code source et des Challenges, accompagnés d'exercices, sont également fournis à des fins d'auto-apprentissage.",[44,45,46,87,107,133],"ul",{},[47,48,49,53],"li",{},[16,50,52],{"href":51},"#refactor-code-to-modern-programming-language-standards","Réusiner le code aux normes d'un langage de programmation moderne",[44,54,55,61,81],{},[47,56,57],{},[16,58,60],{"href":59},"#generate-java-7-and-refactor-to-java-8","Générer en Java 7 et réusiner en Java 8",[47,62,63,67],{},[16,64,66],{"href":65},"#refactor-across-c%2B%2B-standards","Réusiner pour répondre à différentes normes C++",[44,68,69,75],{},[47,70,71],{},[16,72,74],{"href":73},"#migration-refactor-c%2B%2B03-into-c%2B%2B14","Migration : réusiner de la norme C++03 à C++14",[47,76,77],{},[16,78,80],{"href":79},"#downgrade-refactor-c%2B%2B23-to-c%2B%2B11","Retour à une version précédente : réusiner de la norme C++23 à C++11",[47,82,83],{},[16,84,86],{"href":85},"#explain-and-refactor-cobol","Expliquer et réusiner en COBOL",[47,88,89,93],{},[16,90,92],{"href":91},"#refactor-a-language-into-another-language","Réusiner d'un langage à un autre",[44,94,95,101],{},[47,96,97],{},[16,98,100],{"href":99},"#refactor-c-to-rust","Réusiner du C en Rust",[47,102,103],{},[16,104,106],{"href":105},"#refactor-perl-to-python","Réusiner du Perl en Python",[47,108,109,113],{},[16,110,112],{"href":111},"#more-refactoring-hands-on","Autres exemples pratiques de réusinage",[44,114,115,121,127],{},[47,116,117],{},[16,118,120],{"href":119},"#refactor-javascript","Réusiner du JavaScript",[47,122,123],{},[16,124,126],{"href":125},"#refactor-bash-to-zsh-or-sh","Réusiner du Bash en ZSH ou SH",[47,128,129],{},[16,130,132],{"href":131},"#more-use-cases-and-tutorials","Autres cas d'utilisation et tutoriels",[47,134,135],{},[16,136,138],{"href":137},"#key-take-out","Principaux points à retenir",[140,141,52],"h2",{"id":142},"réusiner-le-code-aux-normes-dun-langage-de-programmation-moderne",[12,144,145],{},"Les sections suivantes illustrent comment réusiner le code. Elles fournissent également des explications sur les différences spécifiques au langage de programmation étudié.",[147,148,60],"h3",{"id":149},"générer-en-java-7-et-réusiner-en-java-8",[12,151,152],{},"Un client voulait savoir si GitLab Duo prend en charge Java 7. Lorsque j'ai testé les suggestions de code et les prompts de GitLab Chat pour générer du code en Java 7, j'ai également pensé à des conseils pour effectuer la migration. Claude 3.5 d'Anthropic est capable de comprendre les différences entre divers langages de programmation, tout comme GitLab Duo.",[12,154,155],{},"L'exemple suivant illustre un prompt pour générer du code en Java 7 à l'aide des suggestions de code.",[157,158,163],"pre",{"className":159,"code":160,"language":161,"meta":162,"style":162},"language-java shiki shiki-themes github-light","// Generate a new class for a File Manager. Use Java 7 features only.\nimport java.io.*;\nimport java.nio.file.*;\nimport java.util.*;\n\npublic class FileManager {\n    private Path rootDirectory;\n\n    public FileManager(String rootPath) throws IOException {\n        this.rootDirectory = Paths.get(rootPath);\n        if (!Files.exists(rootDirectory)) {\n            Files.createDirectories(rootDirectory);\n        }\n    }\n\n    public void createFile(String fileName, String content) throws IOException {\n        Path filePath = rootDirectory.resolve(fileName);\n        Files.write(filePath, content.getBytes(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);\n    }\n\n    public String readFile(String fileName) throws IOException {\n        Path filePath = rootDirectory.resolve(fileName);\n        return new String(Files.readAllBytes(filePath));\n    }\n\n    public void deleteFile(String fileName) throws IOException {\n        Path filePath = rootDirectory.resolve(fileName);\n        Files.delete(filePath);\n    }\n\n    public List\u003CString> listFiles() throws IOException {\n        List\u003CString> fileList = new ArrayList\u003C>();\n        try (DirectoryStream\u003CPath> stream = Files.newDirectoryStream(rootDirectory)) {\n            for (Path file : stream) {\n                fileList.add(file.getFileName().toString());\n            }\n        }\n        return fileList;\n    }\n\n    public void copyFile(String sourceFileName, String destinationFileName) throws IOException {\n        Path sourcePath = rootDirectory.resolve(sourceFileName);\n        Path destinationPath = rootDirectory.resolve(destinationFileName);\n        Files.copy(sourcePath, destinationPath, StandardCopyOption.REPLACE_EXISTING);\n    }\n\n    public void moveFile(String sourceFileName, String destinationFileName) throws IOException {\n        Path sourcePath = rootDirectory.resolve(sourceFileName);\n        Path destinationPath = rootDirectory.resolve(destinationFileName);\n        Files.move(sourcePath, destinationPath, StandardCopyOption.REPLACE_EXISTING);\n    }\n\n    public long getFileSize(String fileName) throws IOException {\n        Path filePath = rootDirectory.resolve(fileName);\n        return Files.size(filePath);\n    }\n\n    public boolean fileExists(String fileName) {\n        Path filePath = rootDirectory.resolve(fileName);\n        return Files.exists(filePath);\n    }\n}\n","java","",[164,165,166,175,193,205,217,224,240,249,254,278,299,320,332,338,344,349,377,394,412,417,422,443,456,477,482,487,507,520,531,536,541,565,583,608,623,647,653,658,666,671,676,702,717,732,743,748,753,777,790,803,813,818,823,844,857,869,874,879,897,910,921,926],"code",{"__ignoreMap":162},[167,168,171],"span",{"class":169,"line":170},"line",1,[167,172,174],{"class":173},"sAwPA","// Generate a new class for a File Manager. Use Java 7 features only.\n",[167,176,178,182,186,190],{"class":169,"line":177},2,[167,179,181],{"class":180},"sD7c4","import",[167,183,185],{"class":184},"sgsFI"," java.io.",[167,187,189],{"class":188},"sYu0t","*",[167,191,192],{"class":184},";\n",[167,194,196,198,201,203],{"class":169,"line":195},3,[167,197,181],{"class":180},[167,199,200],{"class":184}," java.nio.file.",[167,202,189],{"class":188},[167,204,192],{"class":184},[167,206,208,210,213,215],{"class":169,"line":207},4,[167,209,181],{"class":180},[167,211,212],{"class":184}," java.util.",[167,214,189],{"class":188},[167,216,192],{"class":184},[167,218,220],{"class":169,"line":219},5,[167,221,223],{"emptyLinePlaceholder":222},true,"\n",[167,225,227,230,233,237],{"class":169,"line":226},6,[167,228,229],{"class":180},"public",[167,231,232],{"class":180}," class",[167,234,236],{"class":235},"s7eDp"," FileManager",[167,238,239],{"class":184}," {\n",[167,241,243,246],{"class":169,"line":242},7,[167,244,245],{"class":180},"    private",[167,247,248],{"class":184}," Path rootDirectory;\n",[167,250,252],{"class":169,"line":251},8,[167,253,223],{"emptyLinePlaceholder":222},[167,255,257,260,262,265,269,272,275],{"class":169,"line":256},9,[167,258,259],{"class":180},"    public",[167,261,236],{"class":235},[167,263,264],{"class":184},"(String ",[167,266,268],{"class":267},"sqxcx","rootPath",[167,270,271],{"class":184},") ",[167,273,274],{"class":180},"throws",[167,276,277],{"class":184}," IOException {\n",[167,279,281,284,287,290,293,296],{"class":169,"line":280},10,[167,282,283],{"class":188},"        this",[167,285,286],{"class":184},".rootDirectory ",[167,288,289],{"class":180},"=",[167,291,292],{"class":184}," Paths.",[167,294,295],{"class":235},"get",[167,297,298],{"class":184},"(rootPath);\n",[167,300,302,305,308,311,314,317],{"class":169,"line":301},11,[167,303,304],{"class":180},"        if",[167,306,307],{"class":184}," (",[167,309,310],{"class":180},"!",[167,312,313],{"class":184},"Files.",[167,315,316],{"class":235},"exists",[167,318,319],{"class":184},"(rootDirectory)) {\n",[167,321,323,326,329],{"class":169,"line":322},12,[167,324,325],{"class":184},"            Files.",[167,327,328],{"class":235},"createDirectories",[167,330,331],{"class":184},"(rootDirectory);\n",[167,333,335],{"class":169,"line":334},13,[167,336,337],{"class":184},"        }\n",[167,339,341],{"class":169,"line":340},14,[167,342,343],{"class":184},"    }\n",[167,345,347],{"class":169,"line":346},15,[167,348,223],{"emptyLinePlaceholder":222},[167,350,352,354,357,360,362,365,368,371,373,375],{"class":169,"line":351},16,[167,353,259],{"class":180},[167,355,356],{"class":180}," void",[167,358,359],{"class":235}," createFile",[167,361,264],{"class":184},[167,363,364],{"class":267},"fileName",[167,366,367],{"class":184},", String ",[167,369,370],{"class":267},"content",[167,372,271],{"class":184},[167,374,274],{"class":180},[167,376,277],{"class":184},[167,378,380,383,385,388,391],{"class":169,"line":379},17,[167,381,382],{"class":184},"        Path filePath ",[167,384,289],{"class":180},[167,386,387],{"class":184}," rootDirectory.",[167,389,390],{"class":235},"resolve",[167,392,393],{"class":184},"(fileName);\n",[167,395,397,400,403,406,409],{"class":169,"line":396},18,[167,398,399],{"class":184},"        Files.",[167,401,402],{"class":235},"write",[167,404,405],{"class":184},"(filePath, content.",[167,407,408],{"class":235},"getBytes",[167,410,411],{"class":184},"(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);\n",[167,413,415],{"class":169,"line":414},19,[167,416,343],{"class":184},[167,418,420],{"class":169,"line":419},20,[167,421,223],{"emptyLinePlaceholder":222},[167,423,425,427,430,433,435,437,439,441],{"class":169,"line":424},21,[167,426,259],{"class":180},[167,428,429],{"class":184}," String ",[167,431,432],{"class":235},"readFile",[167,434,264],{"class":184},[167,436,364],{"class":267},[167,438,271],{"class":184},[167,440,274],{"class":180},[167,442,277],{"class":184},[167,444,446,448,450,452,454],{"class":169,"line":445},22,[167,447,382],{"class":184},[167,449,289],{"class":180},[167,451,387],{"class":184},[167,453,390],{"class":235},[167,455,393],{"class":184},[167,457,459,462,465,468,471,474],{"class":169,"line":458},23,[167,460,461],{"class":180},"        return",[167,463,464],{"class":180}," new",[167,466,467],{"class":235}," String",[167,469,470],{"class":184},"(Files.",[167,472,473],{"class":235},"readAllBytes",[167,475,476],{"class":184},"(filePath));\n",[167,478,480],{"class":169,"line":479},24,[167,481,343],{"class":184},[167,483,485],{"class":169,"line":484},25,[167,486,223],{"emptyLinePlaceholder":222},[167,488,490,492,494,497,499,501,503,505],{"class":169,"line":489},26,[167,491,259],{"class":180},[167,493,356],{"class":180},[167,495,496],{"class":235}," deleteFile",[167,498,264],{"class":184},[167,500,364],{"class":267},[167,502,271],{"class":184},[167,504,274],{"class":180},[167,506,277],{"class":184},[167,508,510,512,514,516,518],{"class":169,"line":509},27,[167,511,382],{"class":184},[167,513,289],{"class":180},[167,515,387],{"class":184},[167,517,390],{"class":235},[167,519,393],{"class":184},[167,521,523,525,528],{"class":169,"line":522},28,[167,524,399],{"class":184},[167,526,527],{"class":235},"delete",[167,529,530],{"class":184},"(filePath);\n",[167,532,534],{"class":169,"line":533},29,[167,535,343],{"class":184},[167,537,539],{"class":169,"line":538},30,[167,540,223],{"emptyLinePlaceholder":222},[167,542,544,546,549,552,555,558,561,563],{"class":169,"line":543},31,[167,545,259],{"class":180},[167,547,548],{"class":184}," List\u003C",[167,550,551],{"class":180},"String",[167,553,554],{"class":184},"> ",[167,556,557],{"class":235},"listFiles",[167,559,560],{"class":184},"() ",[167,562,274],{"class":180},[167,564,277],{"class":184},[167,566,568,571,573,576,578,580],{"class":169,"line":567},32,[167,569,570],{"class":184},"        List\u003C",[167,572,551],{"class":180},[167,574,575],{"class":184},"> fileList ",[167,577,289],{"class":180},[167,579,464],{"class":180},[167,581,582],{"class":184}," ArrayList\u003C>();\n",[167,584,586,589,592,595,598,600,603,606],{"class":169,"line":585},33,[167,587,588],{"class":180},"        try",[167,590,591],{"class":184}," (DirectoryStream\u003C",[167,593,594],{"class":180},"Path",[167,596,597],{"class":184},"> stream ",[167,599,289],{"class":180},[167,601,602],{"class":184}," Files.",[167,604,605],{"class":235},"newDirectoryStream",[167,607,319],{"class":184},[167,609,611,614,617,620],{"class":169,"line":610},34,[167,612,613],{"class":180},"            for",[167,615,616],{"class":184}," (Path file ",[167,618,619],{"class":180},":",[167,621,622],{"class":184}," stream) {\n",[167,624,626,629,632,635,638,641,644],{"class":169,"line":625},35,[167,627,628],{"class":184},"                fileList.",[167,630,631],{"class":235},"add",[167,633,634],{"class":184},"(file.",[167,636,637],{"class":235},"getFileName",[167,639,640],{"class":184},"().",[167,642,643],{"class":235},"toString",[167,645,646],{"class":184},"());\n",[167,648,650],{"class":169,"line":649},36,[167,651,652],{"class":184},"            }\n",[167,654,656],{"class":169,"line":655},37,[167,657,337],{"class":184},[167,659,661,663],{"class":169,"line":660},38,[167,662,461],{"class":180},[167,664,665],{"class":184}," fileList;\n",[167,667,669],{"class":169,"line":668},39,[167,670,343],{"class":184},[167,672,674],{"class":169,"line":673},40,[167,675,223],{"emptyLinePlaceholder":222},[167,677,679,681,683,686,688,691,693,696,698,700],{"class":169,"line":678},41,[167,680,259],{"class":180},[167,682,356],{"class":180},[167,684,685],{"class":235}," copyFile",[167,687,264],{"class":184},[167,689,690],{"class":267},"sourceFileName",[167,692,367],{"class":184},[167,694,695],{"class":267},"destinationFileName",[167,697,271],{"class":184},[167,699,274],{"class":180},[167,701,277],{"class":184},[167,703,705,708,710,712,714],{"class":169,"line":704},42,[167,706,707],{"class":184},"        Path sourcePath ",[167,709,289],{"class":180},[167,711,387],{"class":184},[167,713,390],{"class":235},[167,715,716],{"class":184},"(sourceFileName);\n",[167,718,720,723,725,727,729],{"class":169,"line":719},43,[167,721,722],{"class":184},"        Path destinationPath ",[167,724,289],{"class":180},[167,726,387],{"class":184},[167,728,390],{"class":235},[167,730,731],{"class":184},"(destinationFileName);\n",[167,733,735,737,740],{"class":169,"line":734},44,[167,736,399],{"class":184},[167,738,739],{"class":235},"copy",[167,741,742],{"class":184},"(sourcePath, destinationPath, StandardCopyOption.REPLACE_EXISTING);\n",[167,744,746],{"class":169,"line":745},45,[167,747,343],{"class":184},[167,749,751],{"class":169,"line":750},46,[167,752,223],{"emptyLinePlaceholder":222},[167,754,756,758,760,763,765,767,769,771,773,775],{"class":169,"line":755},47,[167,757,259],{"class":180},[167,759,356],{"class":180},[167,761,762],{"class":235}," moveFile",[167,764,264],{"class":184},[167,766,690],{"class":267},[167,768,367],{"class":184},[167,770,695],{"class":267},[167,772,271],{"class":184},[167,774,274],{"class":180},[167,776,277],{"class":184},[167,778,780,782,784,786,788],{"class":169,"line":779},48,[167,781,707],{"class":184},[167,783,289],{"class":180},[167,785,387],{"class":184},[167,787,390],{"class":235},[167,789,716],{"class":184},[167,791,793,795,797,799,801],{"class":169,"line":792},49,[167,794,722],{"class":184},[167,796,289],{"class":180},[167,798,387],{"class":184},[167,800,390],{"class":235},[167,802,731],{"class":184},[167,804,806,808,811],{"class":169,"line":805},50,[167,807,399],{"class":184},[167,809,810],{"class":235},"move",[167,812,742],{"class":184},[167,814,816],{"class":169,"line":815},51,[167,817,343],{"class":184},[167,819,821],{"class":169,"line":820},52,[167,822,223],{"emptyLinePlaceholder":222},[167,824,826,828,831,834,836,838,840,842],{"class":169,"line":825},53,[167,827,259],{"class":180},[167,829,830],{"class":180}," long",[167,832,833],{"class":235}," getFileSize",[167,835,264],{"class":184},[167,837,364],{"class":267},[167,839,271],{"class":184},[167,841,274],{"class":180},[167,843,277],{"class":184},[167,845,847,849,851,853,855],{"class":169,"line":846},54,[167,848,382],{"class":184},[167,850,289],{"class":180},[167,852,387],{"class":184},[167,854,390],{"class":235},[167,856,393],{"class":184},[167,858,860,862,864,867],{"class":169,"line":859},55,[167,861,461],{"class":180},[167,863,602],{"class":184},[167,865,866],{"class":235},"size",[167,868,530],{"class":184},[167,870,872],{"class":169,"line":871},56,[167,873,343],{"class":184},[167,875,877],{"class":169,"line":876},57,[167,878,223],{"emptyLinePlaceholder":222},[167,880,882,884,887,890,892,894],{"class":169,"line":881},58,[167,883,259],{"class":180},[167,885,886],{"class":180}," boolean",[167,888,889],{"class":235}," fileExists",[167,891,264],{"class":184},[167,893,364],{"class":267},[167,895,896],{"class":184},") {\n",[167,898,900,902,904,906,908],{"class":169,"line":899},59,[167,901,382],{"class":184},[167,903,289],{"class":180},[167,905,387],{"class":184},[167,907,390],{"class":235},[167,909,393],{"class":184},[167,911,913,915,917,919],{"class":169,"line":912},60,[167,914,461],{"class":180},[167,916,602],{"class":184},[167,918,316],{"class":235},[167,920,530],{"class":184},[167,922,924],{"class":169,"line":923},61,[167,925,343],{"class":184},[167,927,929],{"class":169,"line":928},62,[167,930,931],{"class":184},"}\n",[12,933,934],{},"Vous pouvez poursuivre dans votre IDE en suivant ces étapes :",[936,937,938],"ol",{},[47,939,940,941,944],{},"Parcourez et comprenez le code généré : sélectionnez le code dans l'éditeur (en bleu sur la capture d'écran), ouvrez GitLab Duo Chat et envoyez la commande slash ",[164,942,943],{},"/explain"," comme prompt.",[12,946,947],{},[948,949],"img",{"alt":950,"src":951},"Validation du code généré avec la commande slash /explain dans GitLab Duo Chat","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675059/Blog/Content%20Images/intellij_java7_generate_refactor.png",[936,953,954,961,972],{"start":177},[47,955,956,957,960],{},"Réusinez le code Java 7 en Java 8 : sélectionnez le code dans l'éditeur, ouvrez GitLab Chat et envoyez ",[164,958,959],{},"/refactor using Java 8 features"," pour affiner le prompt.",[47,962,963,964,967,968,971],{},"Si vous ne souhaitez pas réusiner le code, créez un nouveau fichier ",[164,965,966],{},"java8.java"," et générez du code spécifique en Java 8 à l'aide des suggestions de code en saisissant le prompt ",[164,969,970],{},"// Generate a new class for a File Manager. Use Java 8 features only.",".",[47,973,974],{},"Continuez à écrire du code en Java 8 dans le même contexte en vous servant des complétions de code alimentées par l'IA.",[12,976,977],{},"Vous pouvez regarder chaque étape dans le vidéo ci-dessous.",[979,980,983,984],"figure",{"className":981},[982],"video_container","\n  ",[985,986,990],"iframe",{"src":987,"frameBorder":988,"allowFullScreen":989},"https://www.youtube.com/embed/XKRv6uBkD2I","0","true"," ",[12,992,993,994,971],{},"Le code source est disponible dans le ",[16,995,998],{"href":996,"rel":997},"https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-generate-refactor-java-7-to-8",[],"projet Challenge GitLab Duo - Générer et réusiner du code de Java 7 à 8",[147,1000,66],{"id":1001},"réusiner-pour-répondre-à-différentes-normes-c",[12,1003,1004],{},"Fruit d'une longue histoire, la norme C++ peut désormais être considérée comme stable et mature. En fonction de l'architecture et des plateformes cibles, la norme prise en charge dépend du compilateur sur le système d'exploitation hôte.",[12,1006,1007],{},"Au cours de ma carrière, j'ai dû prendre en charge 25 distributions Linux et Windows différentes dans des projets open source. D'après mon expérience, les compilateurs ne prennent pas en charge les fonctionnalités de langage plus récentes et les normes C++ de la même manière. Nous avons adopté les fonctionnalités C++11 en 2015, et n'avons jamais évoqué une migration vers C++14 ou C++17.\nLe réusinage des fonctions et des algorithmes pour passer à une nouvelle norme C++ aurait nécessité trop d'efforts, et il aurait fallu recevoir de l'aide pour comprendre les différences. À l'époque, nous faisions nos recherches dans des livres, en ligne, sur Stack Overflow et parfois avec des outils d'aide au réusinage du code.",[12,1009,1010,1011,971],{},"Les assistants alimentés par l'IA et GitLab Duo ont changé la donne : on a maintenant la possibilité de demander aux suggestions de code et à GitLab Chat de fournir du code source dans une norme C++ spécifique. Il est également possible de comparer les différentes sorties.\nL'exemple suivant part d'un prompt pour générer du code source spécifiquement pour la norme C++03. Il implémente un analyseur de configuration simple pour le format de configuration ",[164,1012,1013],{},".ini",[157,1015,1019],{"className":1016,"code":1017,"language":1018,"meta":162,"style":162},"language-c++ shiki shiki-themes github-light","/* Create a config parser which can parse an ini format\nUse C++03 standard only\n */\n\n#include \u003Ciostream>\n#include \u003Cfstream>\n#include \u003Cstring>\n#include \u003Cmap>\n#include \u003Csstream>\n\nclass ConfigParser {\nprivate:\n    std::map\u003Cstd::string, std::map\u003Cstd::string, std::string> > config;\n\npublic:\n    ConfigParser() {}\n\n    bool parse(const std::string& filename) {\n        std::ifstream file(filename.c_str());\n        if (!file.is_open()) {\n            return false;\n        }\n\n        std::string line;\n        std::string currentSection;\n\n        while (std::getline(file, line)) {\n            // Trim whitespace\n            size_t first = line.find_first_not_of(\" \\t\");\n            size_t last = line.find_last_not_of(\" \\t\");\n            if (first == std::string::npos) continue; // Skip empty lines\n            line = line.substr(first, (last - first + 1));\n\n            if (line[0] == '[' && line[line.length() - 1] == ']') {\n                // This is a section\n                currentSection = line.substr(1, line.length() - 2);\n            } else {\n                // This is a key-value pair\n                size_t delimiterPos = line.find('=');\n                if (delimiterPos != std::string::npos) {\n                    std::string key = line.substr(0, delimiterPos);\n                    std::string value = line.substr(delimiterPos + 1);\n                    config[currentSection][key] = value;\n                }\n            }\n        }\n\n        file.close();\n        return true;\n    }\n\n    std::string getValue(const std::string& section, const std::string& key) const {\n        std::map\u003Cstd::string, std::map\u003Cstd::string, std::string> >::const_iterator sectionIt = config.find(section);\n        if (sectionIt != config.end()) {\n            std::map\u003Cstd::string, std::string>::const_iterator keyIt = sectionIt->second.find(key);\n            if (keyIt != sectionIt->second.end()) {\n                return keyIt->second;\n            }\n        }\n        return \"\";\n    }\n\n    void printConfig() const {\n        std::map\u003Cstd::string, std::map\u003Cstd::string, std::string> >::const_iterator sectionIt;\n        for (sectionIt = config.begin(); sectionIt != config.end(); ++sectionIt) {\n            std::cout \u003C\u003C \"[\" \u003C\u003C sectionIt->first \u003C\u003C \"]\" \u003C\u003C std::endl;\n            std::map\u003Cstd::string, std::string>::const_iterator keyIt;\n            for (keyIt = sectionIt->second.begin(); keyIt != sectionIt->second.end(); ++keyIt) {\n                std::cout \u003C\u003C keyIt->first \u003C\u003C \" = \" \u003C\u003C keyIt->second \u003C\u003C std::endl;\n            }\n            std::cout \u003C\u003C std::endl;\n        }\n    }\n};\n\nint main() {\n    ConfigParser parser;\n    if (parser.parse(\"config.ini\")) {\n        std::cout \u003C\u003C \"Config file parsed successfully.\" \u003C\u003C std::endl;\n        parser.printConfig();\n\n        std::cout \u003C\u003C \"Value of 'key1' in 'section1': \" \u003C\u003C parser.getValue(\"section1\", \"key1\") \u003C\u003C std::endl;\n    } else {\n        std::cout \u003C\u003C \"Failed to parse config file.\" \u003C\u003C std::endl;\n    }\n    return 0;\n}\n","c++",[164,1020,1021,1026,1031,1036,1040,1045,1050,1055,1060,1065,1069,1074,1079,1084,1088,1093,1098,1102,1107,1112,1117,1122,1126,1130,1135,1140,1144,1149,1154,1159,1164,1169,1174,1178,1183,1188,1193,1198,1203,1208,1213,1218,1223,1228,1233,1237,1241,1245,1250,1255,1259,1263,1268,1273,1278,1283,1288,1293,1297,1301,1306,1310,1314,1320,1326,1332,1338,1344,1350,1356,1361,1367,1372,1377,1383,1388,1394,1400,1406,1412,1418,1423,1429,1435,1441,1446,1452],{"__ignoreMap":162},[167,1022,1023],{"class":169,"line":170},[167,1024,1025],{},"/* Create a config parser which can parse an ini format\n",[167,1027,1028],{"class":169,"line":177},[167,1029,1030],{},"Use C++03 standard only\n",[167,1032,1033],{"class":169,"line":195},[167,1034,1035],{}," */\n",[167,1037,1038],{"class":169,"line":207},[167,1039,223],{"emptyLinePlaceholder":222},[167,1041,1042],{"class":169,"line":219},[167,1043,1044],{},"#include \u003Ciostream>\n",[167,1046,1047],{"class":169,"line":226},[167,1048,1049],{},"#include \u003Cfstream>\n",[167,1051,1052],{"class":169,"line":242},[167,1053,1054],{},"#include \u003Cstring>\n",[167,1056,1057],{"class":169,"line":251},[167,1058,1059],{},"#include \u003Cmap>\n",[167,1061,1062],{"class":169,"line":256},[167,1063,1064],{},"#include \u003Csstream>\n",[167,1066,1067],{"class":169,"line":280},[167,1068,223],{"emptyLinePlaceholder":222},[167,1070,1071],{"class":169,"line":301},[167,1072,1073],{},"class ConfigParser {\n",[167,1075,1076],{"class":169,"line":322},[167,1077,1078],{},"private:\n",[167,1080,1081],{"class":169,"line":334},[167,1082,1083],{},"    std::map\u003Cstd::string, std::map\u003Cstd::string, std::string> > config;\n",[167,1085,1086],{"class":169,"line":340},[167,1087,223],{"emptyLinePlaceholder":222},[167,1089,1090],{"class":169,"line":346},[167,1091,1092],{},"public:\n",[167,1094,1095],{"class":169,"line":351},[167,1096,1097],{},"    ConfigParser() {}\n",[167,1099,1100],{"class":169,"line":379},[167,1101,223],{"emptyLinePlaceholder":222},[167,1103,1104],{"class":169,"line":396},[167,1105,1106],{},"    bool parse(const std::string& filename) {\n",[167,1108,1109],{"class":169,"line":414},[167,1110,1111],{},"        std::ifstream file(filename.c_str());\n",[167,1113,1114],{"class":169,"line":419},[167,1115,1116],{},"        if (!file.is_open()) {\n",[167,1118,1119],{"class":169,"line":424},[167,1120,1121],{},"            return false;\n",[167,1123,1124],{"class":169,"line":445},[167,1125,337],{},[167,1127,1128],{"class":169,"line":458},[167,1129,223],{"emptyLinePlaceholder":222},[167,1131,1132],{"class":169,"line":479},[167,1133,1134],{},"        std::string line;\n",[167,1136,1137],{"class":169,"line":484},[167,1138,1139],{},"        std::string currentSection;\n",[167,1141,1142],{"class":169,"line":489},[167,1143,223],{"emptyLinePlaceholder":222},[167,1145,1146],{"class":169,"line":509},[167,1147,1148],{},"        while (std::getline(file, line)) {\n",[167,1150,1151],{"class":169,"line":522},[167,1152,1153],{},"            // Trim whitespace\n",[167,1155,1156],{"class":169,"line":533},[167,1157,1158],{},"            size_t first = line.find_first_not_of(\" \\t\");\n",[167,1160,1161],{"class":169,"line":538},[167,1162,1163],{},"            size_t last = line.find_last_not_of(\" \\t\");\n",[167,1165,1166],{"class":169,"line":543},[167,1167,1168],{},"            if (first == std::string::npos) continue; // Skip empty lines\n",[167,1170,1171],{"class":169,"line":567},[167,1172,1173],{},"            line = line.substr(first, (last - first + 1));\n",[167,1175,1176],{"class":169,"line":585},[167,1177,223],{"emptyLinePlaceholder":222},[167,1179,1180],{"class":169,"line":610},[167,1181,1182],{},"            if (line[0] == '[' && line[line.length() - 1] == ']') {\n",[167,1184,1185],{"class":169,"line":625},[167,1186,1187],{},"                // This is a section\n",[167,1189,1190],{"class":169,"line":649},[167,1191,1192],{},"                currentSection = line.substr(1, line.length() - 2);\n",[167,1194,1195],{"class":169,"line":655},[167,1196,1197],{},"            } else {\n",[167,1199,1200],{"class":169,"line":660},[167,1201,1202],{},"                // This is a key-value pair\n",[167,1204,1205],{"class":169,"line":668},[167,1206,1207],{},"                size_t delimiterPos = line.find('=');\n",[167,1209,1210],{"class":169,"line":673},[167,1211,1212],{},"                if (delimiterPos != std::string::npos) {\n",[167,1214,1215],{"class":169,"line":678},[167,1216,1217],{},"                    std::string key = line.substr(0, delimiterPos);\n",[167,1219,1220],{"class":169,"line":704},[167,1221,1222],{},"                    std::string value = line.substr(delimiterPos + 1);\n",[167,1224,1225],{"class":169,"line":719},[167,1226,1227],{},"                    config[currentSection][key] = value;\n",[167,1229,1230],{"class":169,"line":734},[167,1231,1232],{},"                }\n",[167,1234,1235],{"class":169,"line":745},[167,1236,652],{},[167,1238,1239],{"class":169,"line":750},[167,1240,337],{},[167,1242,1243],{"class":169,"line":755},[167,1244,223],{"emptyLinePlaceholder":222},[167,1246,1247],{"class":169,"line":779},[167,1248,1249],{},"        file.close();\n",[167,1251,1252],{"class":169,"line":792},[167,1253,1254],{},"        return true;\n",[167,1256,1257],{"class":169,"line":805},[167,1258,343],{},[167,1260,1261],{"class":169,"line":815},[167,1262,223],{"emptyLinePlaceholder":222},[167,1264,1265],{"class":169,"line":820},[167,1266,1267],{},"    std::string getValue(const std::string& section, const std::string& key) const {\n",[167,1269,1270],{"class":169,"line":825},[167,1271,1272],{},"        std::map\u003Cstd::string, std::map\u003Cstd::string, std::string> >::const_iterator sectionIt = config.find(section);\n",[167,1274,1275],{"class":169,"line":846},[167,1276,1277],{},"        if (sectionIt != config.end()) {\n",[167,1279,1280],{"class":169,"line":859},[167,1281,1282],{},"            std::map\u003Cstd::string, std::string>::const_iterator keyIt = sectionIt->second.find(key);\n",[167,1284,1285],{"class":169,"line":871},[167,1286,1287],{},"            if (keyIt != sectionIt->second.end()) {\n",[167,1289,1290],{"class":169,"line":876},[167,1291,1292],{},"                return keyIt->second;\n",[167,1294,1295],{"class":169,"line":881},[167,1296,652],{},[167,1298,1299],{"class":169,"line":899},[167,1300,337],{},[167,1302,1303],{"class":169,"line":912},[167,1304,1305],{},"        return \"\";\n",[167,1307,1308],{"class":169,"line":923},[167,1309,343],{},[167,1311,1312],{"class":169,"line":928},[167,1313,223],{"emptyLinePlaceholder":222},[167,1315,1317],{"class":169,"line":1316},63,[167,1318,1319],{},"    void printConfig() const {\n",[167,1321,1323],{"class":169,"line":1322},64,[167,1324,1325],{},"        std::map\u003Cstd::string, std::map\u003Cstd::string, std::string> >::const_iterator sectionIt;\n",[167,1327,1329],{"class":169,"line":1328},65,[167,1330,1331],{},"        for (sectionIt = config.begin(); sectionIt != config.end(); ++sectionIt) {\n",[167,1333,1335],{"class":169,"line":1334},66,[167,1336,1337],{},"            std::cout \u003C\u003C \"[\" \u003C\u003C sectionIt->first \u003C\u003C \"]\" \u003C\u003C std::endl;\n",[167,1339,1341],{"class":169,"line":1340},67,[167,1342,1343],{},"            std::map\u003Cstd::string, std::string>::const_iterator keyIt;\n",[167,1345,1347],{"class":169,"line":1346},68,[167,1348,1349],{},"            for (keyIt = sectionIt->second.begin(); keyIt != sectionIt->second.end(); ++keyIt) {\n",[167,1351,1353],{"class":169,"line":1352},69,[167,1354,1355],{},"                std::cout \u003C\u003C keyIt->first \u003C\u003C \" = \" \u003C\u003C keyIt->second \u003C\u003C std::endl;\n",[167,1357,1359],{"class":169,"line":1358},70,[167,1360,652],{},[167,1362,1364],{"class":169,"line":1363},71,[167,1365,1366],{},"            std::cout \u003C\u003C std::endl;\n",[167,1368,1370],{"class":169,"line":1369},72,[167,1371,337],{},[167,1373,1375],{"class":169,"line":1374},73,[167,1376,343],{},[167,1378,1380],{"class":169,"line":1379},74,[167,1381,1382],{},"};\n",[167,1384,1386],{"class":169,"line":1385},75,[167,1387,223],{"emptyLinePlaceholder":222},[167,1389,1391],{"class":169,"line":1390},76,[167,1392,1393],{},"int main() {\n",[167,1395,1397],{"class":169,"line":1396},77,[167,1398,1399],{},"    ConfigParser parser;\n",[167,1401,1403],{"class":169,"line":1402},78,[167,1404,1405],{},"    if (parser.parse(\"config.ini\")) {\n",[167,1407,1409],{"class":169,"line":1408},79,[167,1410,1411],{},"        std::cout \u003C\u003C \"Config file parsed successfully.\" \u003C\u003C std::endl;\n",[167,1413,1415],{"class":169,"line":1414},80,[167,1416,1417],{},"        parser.printConfig();\n",[167,1419,1421],{"class":169,"line":1420},81,[167,1422,223],{"emptyLinePlaceholder":222},[167,1424,1426],{"class":169,"line":1425},82,[167,1427,1428],{},"        std::cout \u003C\u003C \"Value of 'key1' in 'section1': \" \u003C\u003C parser.getValue(\"section1\", \"key1\") \u003C\u003C std::endl;\n",[167,1430,1432],{"class":169,"line":1431},83,[167,1433,1434],{},"    } else {\n",[167,1436,1438],{"class":169,"line":1437},84,[167,1439,1440],{},"        std::cout \u003C\u003C \"Failed to parse config file.\" \u003C\u003C std::endl;\n",[167,1442,1444],{"class":169,"line":1443},85,[167,1445,343],{},[167,1447,1449],{"class":169,"line":1448},86,[167,1450,1451],{},"    return 0;\n",[167,1453,1455],{"class":169,"line":1454},87,[167,1456,931],{},[12,1458,1459,1460,1465,1466,1471,1472,1477,1478,1481,1482,1481,1485,1488],{},"Les mêmes prompts peuvent être utilisés pour l'",[16,1461,1464],{"href":1462,"rel":1463},"https://docs.gitlab.com/user/gitlab_duo_chat/examples/#explain-code-in-the-ide",[],"explication du code",", la ",[16,1467,1470],{"href":1468,"rel":1469},"https://docs.gitlab.com/user/gitlab_duo_chat/examples/#write-tests-in-the-ide",[],"génération de tests",", ainsi que le ",[16,1473,1476],{"href":1474,"rel":1475},"https://docs.gitlab.com/user/gitlab_duo_chat/examples/#refactor-code-in-the-ide",[],"réusinage du code",": ",[164,1479,1480],{},"/explain focus on C++03 features",", ",[164,1483,1484],{},"/tests for C++03 features",[164,1486,1487],{},"/refactor into C++03",".\nLes normes C++ suivantes ont été testées avec les suggestions de code de GitLab Duo :",[44,1490,1491,1494,1497,1500,1503,1506],{},[47,1492,1493],{},"C++03",[47,1495,1496],{},"C++11",[47,1498,1499],{},"C++14",[47,1501,1502],{},"C++17",[47,1504,1505],{},"C++20",[47,1507,1508],{},"C++23",[12,1510,1511,1512,1517],{},"Vous pouvez trouver le code source dans le ",[16,1513,1516],{"href":1514,"rel":1515},"https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-refactor-cpp-standards-config-parser",[],"projet Challenge - Réusiner l'analyseur de configuration aux normes Cpp",".\nDe nombreuses combinaisons différentes permettent de réusiner le code source pour passer d'une norme C++ à une autre. Les exemples suivants illustrent la modernisation de code en C++ en cas de mise à niveau de la version, mais testent également un retour à une version précédente dans le cas où des développeurs ambitieux qui souhaitaient utiliser C++20 ont dû revenir à C++11 pour prendre en charge les environnements de leurs entreprises clientes.",[1519,1520,74],"h4",{"id":1521},"migration-réusiner-de-la-norme-c03-à-c14",[12,1523,1524,1525,1530],{},"L'objectif est de moderniser le code et de comprendre les changements entre C++03 et C++14. Ouvrez le code source ",[16,1526,1529],{"href":1527,"rel":1528},"https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-refactor-cpp-standards-config-parser/-/blob/main/03.cpp?ref_type=heads",[],"03.cpp"," dans l'IDE, sélectionnez-le et utilisez le prompt suivant pour GitLab Chat :",[157,1532,1536],{"className":1533,"code":1534,"language":1535,"meta":162,"style":162},"language-markdown shiki shiki-themes github-light","/refactor into C++14 and explain the changes\n","markdown",[164,1537,1538],{"__ignoreMap":162},[167,1539,1540],{"class":169,"line":170},[167,1541,1534],{"class":184},[12,1543,1544],{},"Réponse potentielle de GitLab Duo Chat :",[157,1546,1548],{"className":1533,"code":1547,"language":1535,"meta":162,"style":162},"…\n\nExplanations of the changes:\n\n1. Default constructor: Changed `ConfigParser() {}` to `ConfigParser() = default;` to use the default constructor.\n2. File opening: Removed `.c_str()` when opening the file, as C++11 and later support `std::string` directly.\n3. Lambda functions: Introduced a lambda function trim to handle string trimming, making the code more readable and reusable.\n4. Auto keyword: Used `auto` for type deduction in various places, improving code readability.\n5. Range-based for loops: In the `printConfig` method, replaced traditional for loops with range-based for loops, which are more concise and less error-prone.\n6. Structured bindings: Used structured bindings in the range-based for loops to directly access key-value pairs.\n7. If statements with initializers: In the `getValue` method, used if statements with initializers to combine the find operation and the check in a single line.\n8. String member functions: Used `front()` and `back()` instead of array-style access for the first and last characters of strings.\n9. Uniform initialization: Used uniform initialization `{}` instead of parentheses `()` for object creation.\n10. Removed `std::endl`: Replaced `std::endl` with `'\\n'` for better performance, as `std::endl` forces a flush of the output buffer.\n\nThese changes make the code more modern, concise, and potentially more efficient while maintaining the same functionality.\n\n",[164,1549,1550,1555,1559,1564,1568,1588,1608,1616,1630,1644,1652,1666,1686,1706,1736,1740],{"__ignoreMap":162},[167,1551,1552],{"class":169,"line":170},[167,1553,1554],{"class":184},"…\n",[167,1556,1557],{"class":169,"line":177},[167,1558,223],{"emptyLinePlaceholder":222},[167,1560,1561],{"class":169,"line":195},[167,1562,1563],{"class":184},"Explanations of the changes:\n",[167,1565,1566],{"class":169,"line":207},[167,1567,223],{"emptyLinePlaceholder":222},[167,1569,1570,1573,1576,1579,1582,1585],{"class":169,"line":219},[167,1571,1572],{"class":267},"1.",[167,1574,1575],{"class":184}," Default constructor: Changed ",[167,1577,1578],{"class":188},"`ConfigParser() {}`",[167,1580,1581],{"class":184}," to ",[167,1583,1584],{"class":188},"`ConfigParser() = default;`",[167,1586,1587],{"class":184}," to use the default constructor.\n",[167,1589,1590,1593,1596,1599,1602,1605],{"class":169,"line":226},[167,1591,1592],{"class":267},"2.",[167,1594,1595],{"class":184}," File opening: Removed ",[167,1597,1598],{"class":188},"`.c_str()`",[167,1600,1601],{"class":184}," when opening the file, as C++11 and later support ",[167,1603,1604],{"class":188},"`std::string`",[167,1606,1607],{"class":184}," directly.\n",[167,1609,1610,1613],{"class":169,"line":242},[167,1611,1612],{"class":267},"3.",[167,1614,1615],{"class":184}," Lambda functions: Introduced a lambda function trim to handle string trimming, making the code more readable and reusable.\n",[167,1617,1618,1621,1624,1627],{"class":169,"line":251},[167,1619,1620],{"class":267},"4.",[167,1622,1623],{"class":184}," Auto keyword: Used ",[167,1625,1626],{"class":188},"`auto`",[167,1628,1629],{"class":184}," for type deduction in various places, improving code readability.\n",[167,1631,1632,1635,1638,1641],{"class":169,"line":256},[167,1633,1634],{"class":267},"5.",[167,1636,1637],{"class":184}," Range-based for loops: In the ",[167,1639,1640],{"class":188},"`printConfig`",[167,1642,1643],{"class":184}," method, replaced traditional for loops with range-based for loops, which are more concise and less error-prone.\n",[167,1645,1646,1649],{"class":169,"line":280},[167,1647,1648],{"class":267},"6.",[167,1650,1651],{"class":184}," Structured bindings: Used structured bindings in the range-based for loops to directly access key-value pairs.\n",[167,1653,1654,1657,1660,1663],{"class":169,"line":301},[167,1655,1656],{"class":267},"7.",[167,1658,1659],{"class":184}," If statements with initializers: In the ",[167,1661,1662],{"class":188},"`getValue`",[167,1664,1665],{"class":184}," method, used if statements with initializers to combine the find operation and the check in a single line.\n",[167,1667,1668,1671,1674,1677,1680,1683],{"class":169,"line":322},[167,1669,1670],{"class":267},"8.",[167,1672,1673],{"class":184}," String member functions: Used ",[167,1675,1676],{"class":188},"`front()`",[167,1678,1679],{"class":184}," and ",[167,1681,1682],{"class":188},"`back()`",[167,1684,1685],{"class":184}," instead of array-style access for the first and last characters of strings.\n",[167,1687,1688,1691,1694,1697,1700,1703],{"class":169,"line":334},[167,1689,1690],{"class":267},"9.",[167,1692,1693],{"class":184}," Uniform initialization: Used uniform initialization ",[167,1695,1696],{"class":188},"`{}`",[167,1698,1699],{"class":184}," instead of parentheses ",[167,1701,1702],{"class":188},"`()`",[167,1704,1705],{"class":184}," for object creation.\n",[167,1707,1708,1711,1714,1717,1720,1722,1725,1728,1731,1733],{"class":169,"line":340},[167,1709,1710],{"class":267},"10.",[167,1712,1713],{"class":184}," Removed ",[167,1715,1716],{"class":188},"`std::endl`",[167,1718,1719],{"class":184},": Replaced ",[167,1721,1716],{"class":188},[167,1723,1724],{"class":184}," with ",[167,1726,1727],{"class":188},"`'\\n'`",[167,1729,1730],{"class":184}," for better performance, as ",[167,1732,1716],{"class":188},[167,1734,1735],{"class":184}," forces a flush of the output buffer.\n",[167,1737,1738],{"class":169,"line":346},[167,1739,223],{"emptyLinePlaceholder":222},[167,1741,1742],{"class":169,"line":351},[167,1743,1744],{"class":184},"These changes make the code more modern, concise, and potentially more efficient while maintaining the same functionality.\n",[12,1746,1747],{},[948,1748],{"alt":1749,"src":1750},"Modifications reflétées dans le code","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675059/Blog/Content%20Images/duo_refactor_cpp_clion_chat_cpp03_to_14_01.png",[12,1752,1753],{},[948,1754],{"alt":1755,"src":1756},"Modifications reflétées dans le code 2","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675060/Blog/Content%20Images/duo_refactor_cpp_clion_chat_cpp03_to_14_02.png",[1519,1758,80],{"id":1759},"retour-à-une-version-précédente-réusiner-de-la-norme-c23-à-c11",[12,1761,1762],{},"Il peut arriver que des développeurs commencent à implémenter une nouvelle fonctionnalité ou une étude de faisabilité en utilisant une norme C++ moderne, par exemple la norme C++20, mais que les versions réellement prises en charge par les environnements des entreprises clientes nécessitent des compilateurs plus anciens compatibles C++11. Le retour à une version précédente a un coût. Il faut évaluer quelles fonctionnalités du langage sont toujours prises en charge et anticiper les autres inconvénients qui pourraient survenir.",[12,1764,1765,1766,1771],{},"Ouvrez le code source ",[16,1767,1770],{"href":1768,"rel":1769},"https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-refactor-cpp-standards-config-parser/-/blob/main/23.cpp?ref_type=heads",[],"23.cpp"," dans l'IDE, sélectionnez-le et saisissez le prompt suivant dans GitLab Duo :",[157,1773,1775],{"className":1533,"code":1774,"language":1535,"meta":162,"style":162},"/refactor into C++11, explain the necessary changes and potential problems\n",[164,1776,1777],{"__ignoreMap":162},[167,1778,1779],{"class":169,"line":170},[167,1780,1774],{"class":184},[12,1782,1544],{},[157,1784,1786],{"className":1533,"code":1785,"language":1535,"meta":162,"style":162},"The main changes required to make this code compatible with C++11 are:\n\n1. Remove the C++23 standard comment, as it's no longer applicable.\n2. Replace `std::string::find_first_not_of` and `std::string::find_last_not_of` with C++11 compatible alternatives in the trim function.\n3. Use `const auto&` instead of `auto` for loop variables to avoid unnecessary copying.\n\nPotential problems in the original code:\n\n1. The original code used C++23 features, which might not be widely supported yet.\n2. The `trim` function used `std::string::find_first_not_of` and `std::string::find_last_not_of`, which are not available in C++11.\n3. The use of `auto` instead of `const auto&` in some loops could lead to unnecessary copying of complex objects.\n\nThese issues have been addressed in the refactored version. The `trim` function now uses `std::find_if_not` with lambda functions to achieve the same result in a C++11 compatible way. The use of `const auto&` ensures that no unnecessary copying occurs when iterating over the config map.\n",[164,1787,1788,1793,1797,1804,1822,1840,1844,1849,1853,1860,1882,1898,1902],{"__ignoreMap":162},[167,1789,1790],{"class":169,"line":170},[167,1791,1792],{"class":184},"The main changes required to make this code compatible with C++11 are:\n",[167,1794,1795],{"class":169,"line":177},[167,1796,223],{"emptyLinePlaceholder":222},[167,1798,1799,1801],{"class":169,"line":195},[167,1800,1572],{"class":267},[167,1802,1803],{"class":184}," Remove the C++23 standard comment, as it's no longer applicable.\n",[167,1805,1806,1808,1811,1814,1816,1819],{"class":169,"line":207},[167,1807,1592],{"class":267},[167,1809,1810],{"class":184}," Replace ",[167,1812,1813],{"class":188},"`std::string::find_first_not_of`",[167,1815,1679],{"class":184},[167,1817,1818],{"class":188},"`std::string::find_last_not_of`",[167,1820,1821],{"class":184}," with C++11 compatible alternatives in the trim function.\n",[167,1823,1824,1826,1829,1832,1835,1837],{"class":169,"line":219},[167,1825,1612],{"class":267},[167,1827,1828],{"class":184}," Use ",[167,1830,1831],{"class":188},"`const auto&`",[167,1833,1834],{"class":184}," instead of ",[167,1836,1626],{"class":188},[167,1838,1839],{"class":184}," for loop variables to avoid unnecessary copying.\n",[167,1841,1842],{"class":169,"line":226},[167,1843,223],{"emptyLinePlaceholder":222},[167,1845,1846],{"class":169,"line":242},[167,1847,1848],{"class":184},"Potential problems in the original code:\n",[167,1850,1851],{"class":169,"line":251},[167,1852,223],{"emptyLinePlaceholder":222},[167,1854,1855,1857],{"class":169,"line":256},[167,1856,1572],{"class":267},[167,1858,1859],{"class":184}," The original code used C++23 features, which might not be widely supported yet.\n",[167,1861,1862,1864,1867,1870,1873,1875,1877,1879],{"class":169,"line":280},[167,1863,1592],{"class":267},[167,1865,1866],{"class":184}," The ",[167,1868,1869],{"class":188},"`trim`",[167,1871,1872],{"class":184}," function used ",[167,1874,1813],{"class":188},[167,1876,1679],{"class":184},[167,1878,1818],{"class":188},[167,1880,1881],{"class":184},", which are not available in C++11.\n",[167,1883,1884,1886,1889,1891,1893,1895],{"class":169,"line":301},[167,1885,1612],{"class":267},[167,1887,1888],{"class":184}," The use of ",[167,1890,1626],{"class":188},[167,1892,1834],{"class":184},[167,1894,1831],{"class":188},[167,1896,1897],{"class":184}," in some loops could lead to unnecessary copying of complex objects.\n",[167,1899,1900],{"class":169,"line":322},[167,1901,223],{"emptyLinePlaceholder":222},[167,1903,1904,1907,1909,1912,1915,1918,1920],{"class":169,"line":334},[167,1905,1906],{"class":184},"These issues have been addressed in the refactored version. The ",[167,1908,1869],{"class":188},[167,1910,1911],{"class":184}," function now uses ",[167,1913,1914],{"class":188},"`std::find_if_not`",[167,1916,1917],{"class":184}," with lambda functions to achieve the same result in a C++11 compatible way. The use of ",[167,1919,1831],{"class":188},[167,1921,1922],{"class":184}," ensures that no unnecessary copying occurs when iterating over the config map.\n",[12,1924,1925],{},[948,1926],{"alt":1927,"src":1928},"The trim function now uses std::find_if_not with lambda functions to achieve the same result in a C++11 compatible way","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675059/Blog/Content%20Images/duo_refactor_cpp_clion_chat_cpp23_to_11_01.png",[12,1930,1931],{},[948,1932],{"alt":1933,"src":1934},"The use of const auto& ensures that no unnecessary copying occurs when iterating over the config map","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675059/Blog/Content%20Images/duo_refactor_cpp_clion_chat_cpp23_to_11_02.png",[12,1936,1937,1941],{},[1938,1939,1940],"strong",{},"Pratique asynchrone",": testez d'autres scénarios de réusinage de version.",[147,1943,86],{"id":1944},"expliquer-et-réusiner-en-cobol",[12,1946,1947,1948,1953],{},"Vous pouvez utiliser GitLab Duo pour expliquer le code source, analyser, corriger et réusiner les programmes COBOL. Bien que je n'aie jamais appris ou codé en COBOL, j'ai trouvé ce ",[16,1949,1952],{"href":1950,"rel":1951},"https://github.com/openmainframeproject/cobol-programming-course",[],"cours de programmation COBOL"," et ses nombreux exemples utiles.",[12,1955,1956],{},"J'ai ensuite demandé à GitLab Chat comment démarrer avec COBOL, créer un programme COBOL et compiler un programme COBOL sur macOS.",[157,1958,1960],{"className":1533,"code":1959,"language":1535,"meta":162,"style":162},"Please explain what COBOL is and its syntax\n\nPlease create a COBOL program that shows the first steps\n\nTell me more about the COBOL compiler. Which system do I need? Can I do it on my macOS?\n\n",[164,1961,1962,1967,1971,1976,1980],{"__ignoreMap":162},[167,1963,1964],{"class":169,"line":170},[167,1965,1966],{"class":184},"Please explain what COBOL is and its syntax\n",[167,1968,1969],{"class":169,"line":177},[167,1970,223],{"emptyLinePlaceholder":222},[167,1972,1973],{"class":169,"line":195},[167,1974,1975],{"class":184},"Please create a COBOL program that shows the first steps\n",[167,1977,1978],{"class":169,"line":207},[167,1979,223],{"emptyLinePlaceholder":222},[167,1981,1982],{"class":169,"line":219},[167,1983,1984],{"class":184},"Tell me more about the COBOL compiler. Which system do I need? Can I do it on my macOS?\n",[12,1986,1987],{},[948,1988],{"alt":1989,"src":1990},"Demande adressée à GitLab Duo Chat pour qu'il explique COBOL et sa syntaxe","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675059/Blog/Content%20Images/vscode_chat_cobol_generate_example.png",[12,1992,1993,1994,1996],{},"Ouvrez un programme COBOL, sélectionnez le code source, passez à GitLab Duo Chat et envoyez le prompt ",[164,1995,943],{}," pour expliquer l'objectif et la fonctionnalité.",[12,1998,1999],{},"Vous pouvez également affiner les prompts pour obtenir des résumés plus généraux, par exemple :",[157,2001,2003],{"className":1533,"code":2002,"language":1535,"meta":162,"style":162},"/explain like I am five\n",[164,2004,2005],{"__ignoreMap":162},[167,2006,2007],{"class":169,"line":170},[167,2008,2002],{"class":184},[2010,2011,2012],"blockquote",{},[12,2013,2014],{},"Conseil : les langages de programmation partagent des algorithmes et des fonctionnalités similaires. GitLab Chat a proposé d'expliquer COBOL en Python. Par conséquent, j'ai ajusté les prompts suivants pour demander une explication en Python.",[157,2016,2018],{"className":1533,"code":2017,"language":1535,"meta":162,"style":162},"/explain in a different programming language\n",[164,2019,2020],{"__ignoreMap":162},[167,2021,2022],{"class":169,"line":170},[167,2023,2017],{"class":184},[12,2025,2026,2027,2030],{},"Vous pouvez également utiliser la commande slash ",[164,2028,2029],{},"/refactor"," comme prompt dans GitLab Chat pour améliorer la qualité du code, résoudre les problèmes potentiels et essayer de réusiner COBOL en Python.",[157,2032,2034],{"className":1533,"code":2033,"language":1535,"meta":162,"style":162},"/refactor fix the environment error\n\n/refactor fix potential problems\n\n/refactor into Python\n",[164,2035,2036,2041,2045,2050,2054],{"__ignoreMap":162},[167,2037,2038],{"class":169,"line":170},[167,2039,2040],{"class":184},"/refactor fix the environment error\n",[167,2042,2043],{"class":169,"line":177},[167,2044,223],{"emptyLinePlaceholder":222},[167,2046,2047],{"class":169,"line":195},[167,2048,2049],{"class":184},"/refactor fix potential problems\n",[167,2051,2052],{"class":169,"line":207},[167,2053,223],{"emptyLinePlaceholder":222},[167,2055,2056],{"class":169,"line":219},[167,2057,2058],{"class":184},"/refactor into Python\n",[12,2060,2061,2062,2067],{},"La vidéo ",[16,2063,2066],{"href":2064,"rel":2065},"https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-explain-refactor-cobol-program",[],"GitLab Duo Coffee Chat - Challenge : expliquer et réusiner des programmes COBOL"," montre toutes les étapes abordées dans un cas d'utilisation pratique. Elle illustre notamment comment trouver une période manquante :",[979,2069,983,2071],{"className":2070},[982],[985,2072,990],{"src":2073,"frameBorder":988,"allowFullScreen":989},"https://www.youtube.com/embed/pwlDmLQMMPo",[140,2075,92],{"id":2076},"réusiner-dun-langage-à-un-autre",[12,2078,2079],{},"La modernisation et l'amélioration de la qualité du code nécessitent parfois de changer de langage de programmation. Des prompts de réusinage similaires dans GitLab Duo peuvent accélérer le processus de migration. L'exemple de COBOL avec Python n'est qu'une des nombreuses exigences en vigueur dans les environnements d'entreprise. Examinons d'autres cas d'utilisation.",[147,2081,100],{"id":2082},"réusiner-du-c-en-rust",[12,2084,2085,2086,2091],{},"Au début de 2024, plusieurs langages de programmation, comme C, ont été accusés de ne pas être à mémoire sécurisée. Les recommandations pour les projets futurs comprennent l'utilisation de ",[16,2087,2090],{"href":2088,"rel":2089},"https://about.gitlab.com/blog/memory-safe-vs-unsafe/",[],"langages à mémoire sécurisée"," comme Rust. Comment démarrer la migration et quels sont les défis à relever ?",[12,2093,2094],{},"Essayons avec un exemple simple en C. Le code a été généré à l'aide des suggestions de code et devrait contenir les informations de base sur le système d'exploitation, comme le nom, la version et la plateforme. Le code C dispose d'une compatibilité multiplateforme sur Windows, Linux et macOS pour la compilation.",[157,2096,2100],{"className":2097,"code":2098,"language":2099,"meta":162,"style":162},"language-c shiki shiki-themes github-light","// Read OS files to identify the platform, name, versions\n// Print them on the terminal\n#include \u003Cstdio.h>\n#include \u003Cstdlib.h>\n#include \u003Cstring.h>\n\n#ifdef _WIN32\n    #include \u003Cwindows.h>\n#elif __APPLE__\n    #include \u003Csys/utsname.h>\n#else\n    #include \u003Csys/utsname.h>\n#endif\n\nvoid get_os_info() {\n    #ifdef _WIN32\n        OSVERSIONINFOEX info;\n        ZeroMemory(&info, sizeof(OSVERSIONINFOEX));\n        info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);\n        GetVersionEx((OSVERSIONINFO*)&info);\n\n        printf(\"Platform: Windows\\n\");\n        printf(\"Version: %d.%d\\n\", info.dwMajorVersion, info.dwMinorVersion);\n        printf(\"Build: %d\\n\", info.dwBuildNumber);\n    #elif __APPLE__\n        struct utsname sys_info;\n        uname(&sys_info);\n\n        printf(\"Platform: macOS\\n\");\n        printf(\"Name: %s\\n\", sys_info.sysname);\n        printf(\"Version: %s\\n\", sys_info.release);\n    #else\n        struct utsname sys_info;\n        uname(&sys_info);\n\n        printf(\"Platform: %s\\n\", sys_info.sysname);\n        printf(\"Name: %s\\n\", sys_info.nodename);\n        printf(\"Version: %s\\n\", sys_info.release);\n    #endif\n}\n\nint main() {\n    get_os_info();\n    return 0;\n}\n","c",[164,2101,2102,2107,2112,2121,2128,2135,2139,2147,2155,2163,2170,2175,2181,2186,2190,2201,2208,2213,2233,2246,2264,2268,2287,2309,2325,2332,2340,2352,2356,2371,2388,2403,2408,2414,2424,2428,2443,2458,2472,2477,2481,2485,2495,2503,2513],{"__ignoreMap":162},[167,2103,2104],{"class":169,"line":170},[167,2105,2106],{"class":173},"// Read OS files to identify the platform, name, versions\n",[167,2108,2109],{"class":169,"line":177},[167,2110,2111],{"class":173},"// Print them on the terminal\n",[167,2113,2114,2117],{"class":169,"line":195},[167,2115,2116],{"class":180},"#include",[167,2118,2120],{"class":2119},"sYBdl"," \u003Cstdio.h>\n",[167,2122,2123,2125],{"class":169,"line":207},[167,2124,2116],{"class":180},[167,2126,2127],{"class":2119}," \u003Cstdlib.h>\n",[167,2129,2130,2132],{"class":169,"line":219},[167,2131,2116],{"class":180},[167,2133,2134],{"class":2119}," \u003Cstring.h>\n",[167,2136,2137],{"class":169,"line":226},[167,2138,223],{"emptyLinePlaceholder":222},[167,2140,2141,2144],{"class":169,"line":242},[167,2142,2143],{"class":180},"#ifdef",[167,2145,2146],{"class":235}," _WIN32\n",[167,2148,2149,2152],{"class":169,"line":251},[167,2150,2151],{"class":180},"    #include",[167,2153,2154],{"class":2119}," \u003Cwindows.h>\n",[167,2156,2157,2160],{"class":169,"line":256},[167,2158,2159],{"class":180},"#elif",[167,2161,2162],{"class":235}," __APPLE__\n",[167,2164,2165,2167],{"class":169,"line":280},[167,2166,2151],{"class":180},[167,2168,2169],{"class":2119}," \u003Csys/utsname.h>\n",[167,2171,2172],{"class":169,"line":301},[167,2173,2174],{"class":180},"#else\n",[167,2176,2177,2179],{"class":169,"line":322},[167,2178,2151],{"class":180},[167,2180,2169],{"class":2119},[167,2182,2183],{"class":169,"line":334},[167,2184,2185],{"class":180},"#endif\n",[167,2187,2188],{"class":169,"line":340},[167,2189,223],{"emptyLinePlaceholder":222},[167,2191,2192,2195,2198],{"class":169,"line":346},[167,2193,2194],{"class":180},"void",[167,2196,2197],{"class":235}," get_os_info",[167,2199,2200],{"class":184},"() {\n",[167,2202,2203,2206],{"class":169,"line":351},[167,2204,2205],{"class":180},"    #ifdef",[167,2207,2146],{"class":235},[167,2209,2210],{"class":169,"line":379},[167,2211,2212],{"class":184},"        OSVERSIONINFOEX info;\n",[167,2214,2215,2218,2221,2224,2227,2230],{"class":169,"line":396},[167,2216,2217],{"class":235},"        ZeroMemory",[167,2219,2220],{"class":184},"(",[167,2222,2223],{"class":180},"&",[167,2225,2226],{"class":184},"info, ",[167,2228,2229],{"class":180},"sizeof",[167,2231,2232],{"class":184},"(OSVERSIONINFOEX));\n",[167,2234,2235,2238,2240,2243],{"class":169,"line":414},[167,2236,2237],{"class":184},"        info.dwOSVersionInfoSize ",[167,2239,289],{"class":180},[167,2241,2242],{"class":180}," sizeof",[167,2244,2245],{"class":184},"(OSVERSIONINFOEX);\n",[167,2247,2248,2251,2254,2256,2259,2261],{"class":169,"line":419},[167,2249,2250],{"class":235},"        GetVersionEx",[167,2252,2253],{"class":184},"((OSVERSIONINFO",[167,2255,189],{"class":180},[167,2257,2258],{"class":184},")",[167,2260,2223],{"class":180},[167,2262,2263],{"class":184},"info);\n",[167,2265,2266],{"class":169,"line":424},[167,2267,223],{"emptyLinePlaceholder":222},[167,2269,2270,2273,2275,2278,2281,2284],{"class":169,"line":445},[167,2271,2272],{"class":235},"        printf",[167,2274,2220],{"class":184},[167,2276,2277],{"class":2119},"\"Platform: Windows",[167,2279,2280],{"class":188},"\\n",[167,2282,2283],{"class":2119},"\"",[167,2285,2286],{"class":184},");\n",[167,2288,2289,2291,2293,2296,2299,2301,2304,2306],{"class":169,"line":458},[167,2290,2272],{"class":235},[167,2292,2220],{"class":184},[167,2294,2295],{"class":2119},"\"Version: ",[167,2297,2298],{"class":188},"%d",[167,2300,971],{"class":2119},[167,2302,2303],{"class":188},"%d\\n",[167,2305,2283],{"class":2119},[167,2307,2308],{"class":184},", info.dwMajorVersion, info.dwMinorVersion);\n",[167,2310,2311,2313,2315,2318,2320,2322],{"class":169,"line":479},[167,2312,2272],{"class":235},[167,2314,2220],{"class":184},[167,2316,2317],{"class":2119},"\"Build: ",[167,2319,2303],{"class":188},[167,2321,2283],{"class":2119},[167,2323,2324],{"class":184},", info.dwBuildNumber);\n",[167,2326,2327,2330],{"class":169,"line":484},[167,2328,2329],{"class":180},"    #elif",[167,2331,2162],{"class":235},[167,2333,2334,2337],{"class":169,"line":489},[167,2335,2336],{"class":180},"        struct",[167,2338,2339],{"class":184}," utsname sys_info;\n",[167,2341,2342,2345,2347,2349],{"class":169,"line":509},[167,2343,2344],{"class":235},"        uname",[167,2346,2220],{"class":184},[167,2348,2223],{"class":180},[167,2350,2351],{"class":184},"sys_info);\n",[167,2353,2354],{"class":169,"line":522},[167,2355,223],{"emptyLinePlaceholder":222},[167,2357,2358,2360,2362,2365,2367,2369],{"class":169,"line":533},[167,2359,2272],{"class":235},[167,2361,2220],{"class":184},[167,2363,2364],{"class":2119},"\"Platform: macOS",[167,2366,2280],{"class":188},[167,2368,2283],{"class":2119},[167,2370,2286],{"class":184},[167,2372,2373,2375,2377,2380,2383,2385],{"class":169,"line":538},[167,2374,2272],{"class":235},[167,2376,2220],{"class":184},[167,2378,2379],{"class":2119},"\"Name: ",[167,2381,2382],{"class":188},"%s\\n",[167,2384,2283],{"class":2119},[167,2386,2387],{"class":184},", sys_info.sysname);\n",[167,2389,2390,2392,2394,2396,2398,2400],{"class":169,"line":543},[167,2391,2272],{"class":235},[167,2393,2220],{"class":184},[167,2395,2295],{"class":2119},[167,2397,2382],{"class":188},[167,2399,2283],{"class":2119},[167,2401,2402],{"class":184},", sys_info.release);\n",[167,2404,2405],{"class":169,"line":567},[167,2406,2407],{"class":180},"    #else\n",[167,2409,2410,2412],{"class":169,"line":585},[167,2411,2336],{"class":180},[167,2413,2339],{"class":184},[167,2415,2416,2418,2420,2422],{"class":169,"line":610},[167,2417,2344],{"class":235},[167,2419,2220],{"class":184},[167,2421,2223],{"class":180},[167,2423,2351],{"class":184},[167,2425,2426],{"class":169,"line":625},[167,2427,223],{"emptyLinePlaceholder":222},[167,2429,2430,2432,2434,2437,2439,2441],{"class":169,"line":649},[167,2431,2272],{"class":235},[167,2433,2220],{"class":184},[167,2435,2436],{"class":2119},"\"Platform: ",[167,2438,2382],{"class":188},[167,2440,2283],{"class":2119},[167,2442,2387],{"class":184},[167,2444,2445,2447,2449,2451,2453,2455],{"class":169,"line":655},[167,2446,2272],{"class":235},[167,2448,2220],{"class":184},[167,2450,2379],{"class":2119},[167,2452,2382],{"class":188},[167,2454,2283],{"class":2119},[167,2456,2457],{"class":184},", sys_info.nodename);\n",[167,2459,2460,2462,2464,2466,2468,2470],{"class":169,"line":660},[167,2461,2272],{"class":235},[167,2463,2220],{"class":184},[167,2465,2295],{"class":2119},[167,2467,2382],{"class":188},[167,2469,2283],{"class":2119},[167,2471,2402],{"class":184},[167,2473,2474],{"class":169,"line":668},[167,2475,2476],{"class":180},"    #endif\n",[167,2478,2479],{"class":169,"line":673},[167,2480,931],{"class":184},[167,2482,2483],{"class":169,"line":678},[167,2484,223],{"emptyLinePlaceholder":222},[167,2486,2487,2490,2493],{"class":169,"line":704},[167,2488,2489],{"class":180},"int",[167,2491,2492],{"class":235}," main",[167,2494,2200],{"class":184},[167,2496,2497,2500],{"class":169,"line":719},[167,2498,2499],{"class":235},"    get_os_info",[167,2501,2502],{"class":184},"();\n",[167,2504,2505,2508,2511],{"class":169,"line":734},[167,2506,2507],{"class":180},"    return",[167,2509,2510],{"class":188}," 0",[167,2512,192],{"class":184},[167,2514,2515],{"class":169,"line":745},[167,2516,931],{"class":184},[12,2518,2519,2520,2527,2528,2530,2531,2533,2534,971],{},"Ouvrez le code source dans ",[16,2521,2524],{"href":2522,"rel":2523},"https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-refactor-c-to-rust/-/blob/897bf57a14bb7be07d842e7f044f93a61456d611/c/os.c",[],[164,2525,2526],{},"os.c"," dans JetBrains CLion, par exemple. Sélectionnez le code source et saisissez le prompt ",[164,2529,943],{}," dans GitLab Chat pour expliquer l'objectif et la fonctionnalité. Entrez ensuite le prompt ",[164,2532,2029],{}," dans GitLab Chat pour réusiner le code C, puis poursuivez avec : ",[164,2535,2536],{},"/refactor into Rust",[12,2538,2539,2540,2543,2544,2547],{},"Initialisez un nouveau projet Rust (astuce : demandez à GitLab Duo Chat) et copiez le code source généré dans le fichier ",[164,2541,2542],{},"src/main.rs",". Exécutez ",[164,2545,2546],{},"cargo build"," pour compiler le code.",[12,2549,2550],{},[948,2551],{"alt":2552,"src":2553},"Initialisez un nouveau projet Rust et copiez le code source généré dans le fichier src/main.rs. Exécution de cargo build pour compiler le code.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675059/Blog/Content%20Images/jetbrains_clion_c_rust.png",[12,2555,2556,2557,2562,2563,2565],{},"Vous pouvez voir toutes les étapes dans la vidéo ",[16,2558,2561],{"href":2559,"rel":2560},"https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-refactor-c-to-rust",[],"GitLab Duo Coffee Chat : Challenge - Réusiner du C en Rust",". Vous verrez en outre une erreur de compilation qui sera corrigée à l'aide de GitLab Chat et de la commande slash ",[164,2564,2029],{},". La session montre également comment améliorer la maintenabilité du nouveau code Rust en renforçant la gestion des erreurs.",[979,2567,983,2569],{"className":2568},[982],[985,2570,990],{"src":2571,"frameBorder":988,"allowFullScreen":989},"https://www.youtube.com/embed/nf8g2ucqvkI",[147,2573,106],{"id":2574},"réusiner-du-perl-en-python",[12,2576,2577],{},"Un script opérationnel tourne sur des serveurs de production. Son auteur a quitté l'entreprise il y a dix ans et personne ne veut y toucher. Ce problème ne concerne peut-être pas qu'un seul script, mais peut-être plusieurs scripts, voire une application entière. Il a été décidé de tout migrer vers Python 3, dans le but de moderniser le code et de comprendre les changements entre Perl et Python.",[12,2579,2580],{},"Récemment, au cours d'un atelier GitLab Duo, un client a demandé s'il était possible d'effectuer une migration directe avec GitLab Duo. En un mot, la réponse est : oui. Pour clarifier : vous pouvez saisir des prompts plus spécifiques dans GitLab Chat pour réusiner le code Perl en Python, comme dans d'autres exemples de cet article.",[12,2582,1765,2583,2586],{},[164,2584,2585],{},"script.pl"," dans l'IDE, sélectionnez-le et ouvrez GitLab Chat.",[157,2588,2592],{"className":2589,"code":2590,"language":2591,"meta":162,"style":162},"language-perl shiki shiki-themes github-light","#!/usr/bin/perl\nuse strict;\nuse warnings;\n\nopen my $md_fh, '\u003C', 'file.md' or die \"Could not open file.md: $!\";\n\nmy $l = 0;\nmy $e = 0;\nmy $h = 0;\n\nwhile (my $line = \u003C$md_fh>) {\n  $l++;\n  if ($line =~ /^\\s*$/) {\n    $e++;\n    next;\n  }\n  if ($line =~ /^#+\\s*(.+)/) {\n    print \"$1\\n\";\n    $h++;   }\n}\n\nprint \"\\nS:\\n\"; print \"L: $l\\n\";\nprint \"E: $e\\n\"; print \"H: $h\\n\";\n","perl",[164,2593,2594,2599,2607,2614,2618,2653,2657,2665,2672,2679,2683,2695,2700,2725,2730,2737,2742,2758,2775,2780,2784,2788,2821],{"__ignoreMap":162},[167,2595,2596],{"class":169,"line":170},[167,2597,2598],{"class":173},"#!/usr/bin/perl\n",[167,2600,2601,2604],{"class":169,"line":177},[167,2602,2603],{"class":180},"use",[167,2605,2606],{"class":184}," strict;\n",[167,2608,2609,2611],{"class":169,"line":195},[167,2610,2603],{"class":180},[167,2612,2613],{"class":184}," warnings;\n",[167,2615,2616],{"class":169,"line":207},[167,2617,223],{"emptyLinePlaceholder":222},[167,2619,2620,2623,2626,2629,2632,2634,2637,2640,2643,2646,2649,2651],{"class":169,"line":219},[167,2621,2622],{"class":188},"open",[167,2624,2625],{"class":180}," my",[167,2627,2628],{"class":184}," $md_fh, ",[167,2630,2631],{"class":2119},"'\u003C'",[167,2633,1481],{"class":184},[167,2635,2636],{"class":2119},"'file.md'",[167,2638,2639],{"class":180}," or",[167,2641,2642],{"class":180}," die",[167,2644,2645],{"class":2119}," \"Could not open file.md: ",[167,2647,2648],{"class":184},"$!",[167,2650,2283],{"class":2119},[167,2652,192],{"class":184},[167,2654,2655],{"class":169,"line":226},[167,2656,223],{"emptyLinePlaceholder":222},[167,2658,2659,2662],{"class":169,"line":242},[167,2660,2661],{"class":180},"my",[167,2663,2664],{"class":184}," $l = 0;\n",[167,2666,2667,2669],{"class":169,"line":251},[167,2668,2661],{"class":180},[167,2670,2671],{"class":184}," $e = 0;\n",[167,2673,2674,2676],{"class":169,"line":256},[167,2675,2661],{"class":180},[167,2677,2678],{"class":184}," $h = 0;\n",[167,2680,2681],{"class":169,"line":280},[167,2682,223],{"emptyLinePlaceholder":222},[167,2684,2685,2688,2690,2692],{"class":169,"line":301},[167,2686,2687],{"class":180},"while",[167,2689,307],{"class":184},[167,2691,2661],{"class":180},[167,2693,2694],{"class":184}," $line = \u003C$md_fh>) {\n",[167,2696,2697],{"class":169,"line":322},[167,2698,2699],{"class":184},"  $l++;\n",[167,2701,2702,2705,2708,2711,2715,2717,2720,2723],{"class":169,"line":334},[167,2703,2704],{"class":180},"  if",[167,2706,2707],{"class":184}," ($line =~ ",[167,2709,2710],{"class":2119},"/^",[167,2712,2714],{"class":2713},"s691h","\\s",[167,2716,189],{"class":2119},[167,2718,2719],{"class":180},"$",[167,2721,2722],{"class":2119},"/",[167,2724,896],{"class":184},[167,2726,2727],{"class":169,"line":340},[167,2728,2729],{"class":184},"    $e++;\n",[167,2731,2732,2735],{"class":169,"line":346},[167,2733,2734],{"class":180},"    next",[167,2736,192],{"class":184},[167,2738,2739],{"class":169,"line":351},[167,2740,2741],{"class":184},"  }\n",[167,2743,2744,2746,2748,2751,2753,2756],{"class":169,"line":379},[167,2745,2704],{"class":180},[167,2747,2707],{"class":184},[167,2749,2750],{"class":2119},"/^#+",[167,2752,2714],{"class":2713},[167,2754,2755],{"class":2119},"*(.+)/",[167,2757,896],{"class":184},[167,2759,2760,2763,2766,2769,2771,2773],{"class":169,"line":396},[167,2761,2762],{"class":188},"    print",[167,2764,2765],{"class":2119}," \"",[167,2767,2768],{"class":184},"$1",[167,2770,2280],{"class":188},[167,2772,2283],{"class":2119},[167,2774,192],{"class":184},[167,2776,2777],{"class":169,"line":414},[167,2778,2779],{"class":184},"    $h++;   }\n",[167,2781,2782],{"class":169,"line":419},[167,2783,931],{"class":184},[167,2785,2786],{"class":169,"line":424},[167,2787,223],{"emptyLinePlaceholder":222},[167,2789,2790,2793,2795,2797,2800,2802,2804,2807,2809,2812,2815,2817,2819],{"class":169,"line":445},[167,2791,2792],{"class":188},"print",[167,2794,2765],{"class":2119},[167,2796,2280],{"class":188},[167,2798,2799],{"class":2119},"S:",[167,2801,2280],{"class":188},[167,2803,2283],{"class":2119},[167,2805,2806],{"class":184},"; ",[167,2808,2792],{"class":188},[167,2810,2811],{"class":2119}," \"L: ",[167,2813,2814],{"class":184},"$l",[167,2816,2280],{"class":188},[167,2818,2283],{"class":2119},[167,2820,192],{"class":184},[167,2822,2823,2825,2828,2831,2833,2835,2837,2839,2842,2845,2847,2849],{"class":169,"line":458},[167,2824,2792],{"class":188},[167,2826,2827],{"class":2119}," \"E: ",[167,2829,2830],{"class":184},"$e",[167,2832,2280],{"class":188},[167,2834,2283],{"class":2119},[167,2836,2806],{"class":184},[167,2838,2792],{"class":188},[167,2840,2841],{"class":2119}," \"H: ",[167,2843,2844],{"class":184},"$h",[167,2846,2280],{"class":188},[167,2848,2283],{"class":2119},[167,2850,192],{"class":184},[12,2852,2853],{},"You can use the following prompts to:",[936,2855,2856,2864],{},[47,2857,2858,2860,2861,2863],{},[164,2859,943],{}," its purpose, and ",[164,2862,2029],{}," to improve the code.",[47,2865,2866,2869],{},[164,2867,2868],{},"/refactor into Python"," pour obtenir un script Python fonctionnel.",[12,2871,2872],{},[948,2873],{"alt":2874,"src":2875},"Réusinage en Python","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675059/Blog/Content%20Images/pycharm_duo_refactor_perl_python.png",[2010,2877,2878,2887],{},[12,2879,2880,2881,2886],{},"Astuce : vous pouvez réusiner le code Perl dans d'autres langages cibles. La vidéo ",[16,2882,2885],{"href":2883,"rel":2884},"https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-refactor-perl-python",[],"GitLab Duo Coffee Chat : Challenge - Réusiner du Perl en Python"," fournit des exemples avec PHP, Ruby, Rust, Go, Java, VB.NET, C# et d'autres langages.",[2010,2888,2889],{},[12,2890,2891,2892,2897],{},"Si vous souhaitez continuer à utiliser des scripts Perl, vous pouvez configurer ",[16,2893,2896],{"href":2894,"rel":2895},"https://docs.gitlab.com/user/project/repository/code_suggestions/supported_extensions/#add-support-for-more-languages",[],"Perl comme langage supplémentaire"," en vous servant des suggestions de code de GitLab Duo. GitLab Chat comprend déjà Perl et peut vous aider si vous utilisez des questions et des prompts de commande slash, comme vous pouvez le voir dans la vidéo ci-dessous.",[979,2899,983,2901],{"className":2900},[982],[985,2902,990],{"src":2903,"frameBorder":988,"allowFullScreen":989},"https://www.youtube.com/embed/03HGhxXg9lw",[140,2905,112],{"id":2906},"autres-exemples-pratiques-de-réusinage",[147,2908,120],{"id":2909},"réusiner-du-javascript",[12,2911,2912],{},"Eddie Jaoude montre dans un exemple pratique comment réusiner du code JavaScript pour améliorer sa qualité ou ajouter des fonctionnalités.",[979,2914,983,2916],{"className":2915},[982],[985,2917,990],{"src":2918,"frameBorder":988,"allowFullScreen":989},"https://www.youtube.com/embed/mHn8KOzpPNY",[147,2920,126],{"id":2921},"réusiner-du-bash-en-zsh-ou-sh",[12,2923,2924],{},"J'utilise Bash comme shell depuis 20 ans et je suis récemment passé à ZSH sur macOS. À cause de ce changement, mon script ne fonctionnait pas et mon terminal affichait des erreurs inconnues. Les limitations du shell sont un autre cas d'utilisation. Elles justifient également le réusinage : certains systèmes d'exploitation ou distributions Linux/Unix ne fournissent pas Bash, mais uniquement SH, par exemple Alpine.",[12,2926,2927],{},[948,2928],{"alt":2929,"src":2930},"Réusinage de scripts shell","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675059/Blog/Content%20Images/intellj_refactor_shell_scripts.png",[12,2932,2933,2934,2939,2940,2942,2943,2945],{},"Le ",[16,2935,2938],{"href":2936,"rel":2937},"https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-refactor-shell-scripts",[],"GitLab Duo Coffee Chat : Challenge - Réusiner des scripts shell"," fournit un exemple avec un programme C qui peut suivre les fichiers syslog et un script de compilation écrit en Bash. Tout au long du Challenge, GitLab Chat reçoit des requêtes avec des prompts ",[164,2941,943],{}," et ",[164,2944,2029],{}," pour améliorer le code. Il est également possible de réusiner du Bash en SH ou ZSH pour assurer la conformité à POSIX. À la fin de la session, GitLab Chat doit fournir cinq implémentations de scripts shell différentes et expliquer les principaux résumés.",[979,2947,983,2949],{"className":2948},[982],[985,2950,990],{"src":2951,"frameBorder":988,"allowFullScreen":989},"https://www.youtube.com/embed/mssqYjlKGzU",[147,2953,132],{"id":2954},"autres-cas-dutilisation-et-tutoriels",[44,2956,2957,2964,2971],{},[47,2958,2959],{},[16,2960,2963],{"href":2961,"rel":2962},"https://docs.gitlab.com/user/gitlab_duo/use_cases/",[],"Documentation : cas d'utilisation de GitLab Duo",[47,2965,2966],{},[16,2967,2970],{"href":2968,"rel":2969},"https://about.gitlab.com/blog/top-tips-for-efficient-ai-powered-code-suggestions-with-gitlab-duo/",[],"Tutoriel : meilleurs conseils pour obtenir des suggestions de code alimentées par l'IA efficaces avec GitLab Duo",[47,2972,2973],{},[16,2974,2977],{"href":2975,"rel":2976},"https://about.gitlab.com/blog/10-best-practices-for-using-ai-powered-gitlab-duo-chat/",[],"Tutoriel : 10 bonnes pratiques pour utiliser GitLab Duo Chat alimenté par l'IA",[140,2979,138],{"id":2980},"principaux-points-à-retenir",[936,2982,2983,2986,2989,2992,2995,2998,3001],{},[47,2984,2985],{},"GitLab Duo fournit une aide efficace pour expliquer et réusiner le code. 2. Il est possible de réusiner le code pour l'adapter aux normes de différents langages et poser des questions de suivi dans GitLab Chat.",[47,2987,2988],{},"Les prompts de suggestion de code peuvent générer des normes spécifiques à des langages de programmation, et la complétion de code respecte le contexte du code actuel.",[47,2990,2991],{},"Le réusinage du code dans de nouveaux langages de programmation contribue aux plans de migration et de modernisation à long terme.",[47,2993,2994],{},"Le code peut être « rétrogradé » à une version précédente lorsque les normes d'un langage sont prises en charge par un ancien système.",[47,2996,2997],{},"GitLab Duo peut expliquer du code complexe et des langages de programmation avec différents exemples de langages de programmation.",[47,2999,3000],{},"La mise à jour vers Claude 3.5 d'Anthropic sur GitLab.com a amélioré une fois de plus la qualité et la rapidité des suggestions de code et de GitLab Chat (il est recommandé de mettre à niveau GitLab Auto-géré vers la version 17.3).",[47,3002,3003],{},"Votre seule limite : votre imagination et les points de friction en production.",[12,3005,3006],{},"Apprenez-en plus sur les suggestions de code et les workflows efficaces de GitLab Chat, et commencez à réusiner du code alimenté par l'IA avec GitLab Duo dès aujourd'hui !",[2010,3008,3009],{},[12,3010,3011],{},[16,3012,3015],{"href":3013,"rel":3014},"https://about.gitlab.com/sales/?type=free-trial&toggle=gitlab-duo-pro_",[],"Commencez votre essai gratuit de GitLab Duo !",[3017,3018,3019],"style",{},"html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sqxcx, html code.shiki .sqxcx{--shiki-default:#E36209}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html pre.shiki code .s691h, html code.shiki .s691h{--shiki-default:#22863A;--shiki-default-font-weight:bold}",{"title":162,"searchDepth":177,"depth":177,"links":3021},[3022,3027,3031,3036],{"id":142,"depth":177,"text":52,"children":3023},[3024,3025,3026],{"id":149,"depth":195,"text":60},{"id":1001,"depth":195,"text":66},{"id":1944,"depth":195,"text":86},{"id":2076,"depth":177,"text":92,"children":3028},[3029,3030],{"id":2082,"depth":195,"text":100},{"id":2574,"depth":195,"text":106},{"id":2906,"depth":177,"text":112,"children":3032},[3033,3034,3035],{"id":2909,"depth":195,"text":120},{"id":2921,"depth":195,"text":126},{"id":2954,"depth":195,"text":132},{"id":2980,"depth":177,"text":138},"ai","2024-08-26","Ce tutoriel détaillé à destination des développeurs leur permet d'utiliser l'IA pour moderniser leur code en passant à un nouveau langage de programmation. Il leur offre également l'occasion d'acquérir des connaissances sur les nouvelles fonctionnalités associées à ce langage.","md",null,false,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749662465/Blog/Hero%20Images/GitLab_Duo_Workflow_Unified_Data_Store__1_.png",{},"/fr-fr/blog/refactor-code-into-modern-languages-with-ai-powered-gitlab-duo",{"title":5,"description":3039,"ogTitle":5,"ogDescription":3039,"noIndex":3042,"ogImage":3043,"ogUrl":3047,"ogSiteName":3048,"ogType":3049,"canonicalUrls":3047},"https://about.gitlab.com/blog/refactor-code-into-modern-languages-with-ai-powered-gitlab-duo","https://about.gitlab.com","article","refactor-code-into-modern-languages-with-ai-powered-gitlab-duo","fr-fr/blog/refactor-code-into-modern-languages-with-ai-powered-gitlab-duo",[3053,3054,3055],"AI","tutorial","DevSecOps","BlogPost","68RtL_R_dQJX0ZxZozQy8ak95nNxV87sjQrblcrG9EA",{"logo":3059,"freeTrial":3064,"sales":3069,"login":3074,"items":3079,"search":3408,"minimal":3444,"duo":3463,"switchNav":3472,"pricingDeployment":3483},{"config":3060},{"href":3061,"dataGaName":3062,"dataGaLocation":3063},"/fr-fr/","gitlab logo","header",{"text":3065,"config":3066},"Commencer un essai gratuit",{"href":3067,"dataGaName":3068,"dataGaLocation":3063},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/fr-fr&glm_content=default-saas-trial/","free trial",{"text":3070,"config":3071},"Demander une démo",{"href":3072,"dataGaName":3073,"dataGaLocation":3063},"/fr-fr/sales/?contact-topic=request-demo","sales",{"text":3075,"config":3076},"Connexion",{"href":3077,"dataGaName":3078,"dataGaLocation":3063},"https://gitlab.com/users/sign_in/","sign in",[3080,3109,3211,3216,3330,3386],{"text":3081,"config":3082,"menu":3084},"Plateforme",{"dataNavLevelOne":3083},"platform",{"type":3085,"columns":3086},"cards",[3087,3093,3101],{"title":3081,"description":3088,"link":3089},"La plateforme d'orchestration intelligente pour le DevSecOps",{"text":3090,"config":3091},"Explorer notre plateforme",{"href":3092,"dataGaName":3083,"dataGaLocation":3063},"/fr-fr/platform/",{"title":3094,"description":3095,"link":3096},"GitLab Duo Agent Platform","L'IA agentique pour l'ensemble du cycle de développement logiciel",{"text":3097,"config":3098},"Découvrir GitLab Duo",{"href":3099,"dataGaName":3100,"dataGaLocation":3063},"/fr-fr/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":3102,"description":3103,"link":3104},"Pourquoi GitLab ?","Découvrez les principales raisons pour lesquelles les entreprises choisissent GitLab",{"text":3105,"config":3106},"En savoir plus",{"href":3107,"dataGaName":3108,"dataGaLocation":3063},"/fr-fr/why-gitlab/","why gitlab",{"text":3110,"left":222,"config":3111,"menu":3113},"Produit",{"dataNavLevelOne":3112},"solutions",{"type":3114,"link":3115,"columns":3119,"feature":3190},"lists",{"text":3116,"config":3117},"Voir toutes les solutions",{"href":3118,"dataGaName":3112,"dataGaLocation":3063},"/fr-fr/solutions/",[3120,3145,3168],{"title":3121,"description":3122,"link":3123,"items":3128},"Automatisation","CI/CD et automatisation pour accélérer le déploiement",{"config":3124},{"icon":3125,"href":3126,"dataGaName":3127,"dataGaLocation":3063},"AutomatedCodeAlt","/fr-fr/solutions/delivery-automation/","automated software delivery",[3129,3133,3136,3141],{"text":3130,"config":3131},"CI/CD",{"href":3132,"dataGaLocation":3063,"dataGaName":3130},"/fr-fr/solutions/continuous-integration/",{"text":3094,"config":3134},{"href":3099,"dataGaLocation":3063,"dataGaName":3135},"gitlab duo agent platform - product menu",{"text":3137,"config":3138},"Gestion du code source",{"href":3139,"dataGaLocation":3063,"dataGaName":3140},"/fr-fr/solutions/source-code-management/","Source Code Management",{"text":3142,"config":3143},"Livraison de logiciels automatisée",{"href":3126,"dataGaLocation":3063,"dataGaName":3144},"Automated software delivery",{"title":3146,"description":3147,"link":3148,"items":3153},"Sécurité","Livrez du code plus rapidement sans compromettre la sécurité",{"config":3149},{"href":3150,"dataGaName":3151,"dataGaLocation":3063,"icon":3152},"/fr-fr/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[3154,3158,3163],{"text":3155,"config":3156},"Tests de sécurité des applications",{"href":3150,"dataGaName":3157,"dataGaLocation":3063},"Application security testing",{"text":3159,"config":3160},"Sécurité de la chaîne d'approvisionnement logicielle",{"href":3161,"dataGaLocation":3063,"dataGaName":3162},"/fr-fr/solutions/supply-chain/","Software supply chain security",{"text":3164,"config":3165},"Conformité logicielle",{"href":3166,"dataGaName":3167,"dataGaLocation":3063},"/fr-fr/solutions/software-compliance/","software compliance",{"title":3169,"link":3170,"items":3175},"Mesures",{"config":3171},{"icon":3172,"href":3173,"dataGaName":3174,"dataGaLocation":3063},"DigitalTransformation","/fr-fr/solutions/visibility-measurement/","visibility and measurement",[3176,3180,3185],{"text":3177,"config":3178},"Visibilité et mesures",{"href":3173,"dataGaLocation":3063,"dataGaName":3179},"Visibility and Measurement",{"text":3181,"config":3182},"Gestion de la chaîne de valeur",{"href":3183,"dataGaLocation":3063,"dataGaName":3184},"/fr-fr/solutions/value-stream-management/","Value Stream Management",{"text":3186,"config":3187},"Analyses et informations",{"href":3188,"dataGaLocation":3063,"dataGaName":3189},"/fr-fr/solutions/analytics-and-insights/","Analytics and insights",{"title":3191,"type":3114,"items":3192},"GitLab",[3193,3199,3205],{"text":3194,"config":3195},"Entreprises",{"icon":3196,"href":3197,"dataGaLocation":3063,"dataGaName":3198},"Building","/fr-fr/enterprise/","enterprise",{"text":3200,"config":3201},"Pour les PME",{"icon":3202,"href":3203,"dataGaLocation":3063,"dataGaName":3204},"Work","/fr-fr/small-business/","small business",{"text":3206,"config":3207},"Pour le secteur public",{"icon":3208,"href":3209,"dataGaLocation":3063,"dataGaName":3210},"Organization","/fr-fr/solutions/public-sector/","public sector",{"text":3212,"config":3213},"Tarifs",{"href":3214,"dataGaName":3215,"dataGaLocation":3063,"dataNavLevelOne":3215},"/fr-fr/pricing/","pricing",{"text":3217,"config":3218,"menu":3220},"Ressources",{"dataNavLevelOne":3219},"resources",{"type":3114,"link":3221,"columns":3225,"feature":3319},{"text":3222,"config":3223},"Afficher toutes les ressources",{"href":3224,"dataGaName":3219,"dataGaLocation":3063},"/fr-fr/resources/",[3226,3259,3286],{"title":3227,"items":3228},"Premiers pas",[3229,3234,3239,3244,3249,3254],{"text":3230,"config":3231},"Installation",{"href":3232,"dataGaName":3233,"dataGaLocation":3063},"/fr-fr/install/","install",{"text":3235,"config":3236},"Guides de démarrage",{"href":3237,"dataGaName":3238,"dataGaLocation":3063},"/fr-fr/get-started/","quick setup checklists",{"text":3240,"config":3241},"Apprentissage",{"href":3242,"dataGaLocation":3063,"dataGaName":3243},"https://university.gitlab.com/","learn",{"text":3245,"config":3246},"Documentation",{"href":3247,"dataGaName":3248,"dataGaLocation":3063},"https://docs.gitlab.com/","product documentation",{"text":3250,"config":3251},"Vidéos sur les bonnes pratiques",{"href":3252,"dataGaName":3253,"dataGaLocation":3063},"/fr-fr/getting-started-videos/","best practice videos",{"text":3255,"config":3256},"Intégrations",{"href":3257,"dataGaName":3258,"dataGaLocation":3063},"/fr-fr/integrations/","integrations",{"title":3260,"items":3261},"Découvrir",[3262,3267,3272,3277,3281],{"text":3263,"config":3264},"Témoignages clients",{"href":3265,"dataGaName":3266,"dataGaLocation":3063},"/fr-fr/customers/","customer success stories",{"text":3268,"config":3269},"Blog",{"href":3270,"dataGaName":3271,"dataGaLocation":3063},"/fr-fr/blog/","blog",{"text":3273,"config":3274},"Demo Hub",{"href":3275,"dataGaName":3276,"dataGaLocation":3063},"/fr-fr/demo-hub/","demo hub",{"text":3278,"config":3279},"The Source",{"href":3280,"dataGaName":3271,"dataGaLocation":3063},"/fr-fr/the-source/",{"text":3282,"config":3283},"Travail à distance",{"href":3284,"dataGaName":3285,"dataGaLocation":3063},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":3287,"items":3288},"Connecter",[3289,3294,3299,3304,3309,3314],{"text":3290,"config":3291},"Services GitLab",{"href":3292,"dataGaName":3293,"dataGaLocation":3063},"/fr-fr/services/","services",{"text":3295,"config":3296},"Contribuer",{"href":3297,"dataGaName":3298,"dataGaLocation":3063},"https://contributors.gitlab.com","contribute",{"text":3300,"config":3301},"Communauté",{"href":3302,"dataGaName":3303,"dataGaLocation":3063},"/community/","community",{"text":3305,"config":3306},"Forum",{"href":3307,"dataGaName":3308,"dataGaLocation":3063},"https://forum.gitlab.com/","forum",{"text":3310,"config":3311},"Événements",{"href":3312,"dataGaName":3313,"dataGaLocation":3063},"/events/","events",{"text":3315,"config":3316},"Partenaires",{"href":3317,"dataGaName":3318,"dataGaLocation":3063},"/fr-fr/partners/","partners",{"config":3320,"title":3323,"text":3324,"link":3325},{"background":3321,"textColor":3322},"url('https://res.cloudinary.com/about-gitlab-com/image/upload/v1777322348/qpq8yrgn8knii57omj0c.png')","#000","Nouveautés de GitLab","Découvrez les dernières fonctionnalités et améliorations.",{"text":3326,"config":3327},"Lire les articles les plus récents",{"href":3328,"dataGaName":3329,"dataGaLocation":3063},"/fr-fr/whats-new/","whats new",{"text":3331,"config":3332,"menu":3334},"Société",{"dataNavLevelOne":3333},"company",{"type":3114,"columns":3335},[3336],{"items":3337},[3338,3343,3349,3351,3356,3361,3366,3371,3376,3381],{"text":3339,"config":3340},"À propos",{"href":3341,"dataGaName":3342,"dataGaLocation":3063},"/fr-fr/company/","about",{"text":3344,"config":3345,"footerGa":3348},"Carrières",{"href":3346,"dataGaName":3347,"dataGaLocation":3063},"/jobs/","jobs",{"dataGaName":3347},{"text":3310,"config":3350},{"href":3312,"dataGaName":3313,"dataGaLocation":3063},{"text":3352,"config":3353},"Leadership",{"href":3354,"dataGaName":3355,"dataGaLocation":3063},"/company/team/e-group/","leadership",{"text":3357,"config":3358},"Manuel",{"href":3359,"dataGaName":3360,"dataGaLocation":3063},"https://handbook.gitlab.com/","handbook",{"text":3362,"config":3363},"Relations avec les investisseurs",{"href":3364,"dataGaName":3365,"dataGaLocation":3063},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":3367,"config":3368},"Trust Center",{"href":3369,"dataGaName":3370,"dataGaLocation":3063},"/fr-fr/security/","trust center",{"text":3372,"config":3373},"Centre pour la transparence de l'IA",{"href":3374,"dataGaName":3375,"dataGaLocation":3063},"/fr-fr/ai-transparency-center/","ai transparency center",{"text":3377,"config":3378},"Newsletter",{"href":3379,"dataGaName":3380,"dataGaLocation":3063},"/company/contact/#contact-forms","newsletter",{"text":3382,"config":3383},"Presse",{"href":3384,"dataGaName":3385,"dataGaLocation":3063},"/press/","press",{"text":3387,"config":3388,"menu":3389},"Nous contacter",{"dataNavLevelOne":3333},{"type":3114,"columns":3390},[3391],{"items":3392},[3393,3398,3403],{"text":3394,"config":3395},"Contacter l'équipe commerciale",{"href":3396,"dataGaName":3397,"dataGaLocation":3063},"/fr-fr/sales/","talk to sales",{"text":3399,"config":3400},"Assistance GitLab",{"href":3401,"dataGaName":3402,"dataGaLocation":3063},"https://support.gitlab.com/hc/en-us","support portal",{"text":3404,"config":3405},"Portail clients GitLab",{"href":3406,"dataGaName":3407,"dataGaLocation":3063},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":3409,"login":3410,"suggestions":3417},"Fermer",{"text":3411,"link":3412},"Pour rechercher des dépôts et des projets, connectez-vous à",{"text":3413,"config":3414},"GitLab.com",{"href":3077,"dataGaName":3415,"dataGaLocation":3416},"search login","search",{"text":3418,"default":3419},"Suggestions",[3420,3423,3428,3430,3435,3440],{"text":3094,"config":3421},{"href":3099,"dataGaName":3422,"dataGaLocation":3416},"GitLab Duo Agent Platform",{"text":3424,"config":3425},"Suggestions de code (IA)",{"href":3426,"dataGaName":3427,"dataGaLocation":3416},"/fr-fr/solutions/code-suggestions/","Code Suggestions (AI)",{"text":3130,"config":3429},{"href":3132,"dataGaName":3130,"dataGaLocation":3416},{"text":3431,"config":3432},"GitLab sur AWS",{"href":3433,"dataGaName":3434,"dataGaLocation":3416},"/fr-fr/partners/technology-partners/aws/","GitLab on AWS",{"text":3436,"config":3437},"GitLab sur Google Cloud",{"href":3438,"dataGaName":3439,"dataGaLocation":3416},"/fr-fr/partners/technology-partners/google-cloud-platform/","GitLab on Google Cloud",{"text":3441,"config":3442},"Pourquoi utiliser GitLab ?",{"href":3107,"dataGaName":3443,"dataGaLocation":3416},"Why GitLab?",{"freeTrial":3445,"mobileIcon":3450,"desktopIcon":3455,"secondaryButton":3458},{"text":3446,"config":3447},"Commencer votre essai gratuit",{"href":3448,"dataGaName":3068,"dataGaLocation":3449},"https://gitlab.com/-/trials/new/","nav",{"altText":3451,"config":3452},"Icône GitLab",{"src":3453,"dataGaName":3454,"dataGaLocation":3449},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":3451,"config":3456},{"src":3457,"dataGaName":3454,"dataGaLocation":3449},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":3459,"config":3460},"Commencer",{"href":3461,"dataGaName":3462,"dataGaLocation":3449},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/fr-fr/get-started/","get started",{"freeTrial":3464,"mobileIcon":3468,"desktopIcon":3470},{"text":3465,"config":3466},"En savoir plus sur GitLab Duo",{"href":3099,"dataGaName":3467,"dataGaLocation":3449},"gitlab duo",{"altText":3451,"config":3469},{"src":3453,"dataGaName":3454,"dataGaLocation":3449},{"altText":3451,"config":3471},{"src":3457,"dataGaName":3454,"dataGaLocation":3449},{"button":3473,"mobileIcon":3478,"desktopIcon":3480},{"text":3474,"config":3475},"/switch",{"href":3476,"dataGaName":3477,"dataGaLocation":3449},"#contact","switch",{"altText":3451,"config":3479},{"src":3453,"dataGaName":3454,"dataGaLocation":3449},{"altText":3451,"config":3481},{"src":3482,"dataGaName":3454,"dataGaLocation":3449},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":3484,"mobileIcon":3489,"desktopIcon":3491},{"text":3485,"config":3486},"Retour aux tarifs",{"href":3214,"dataGaName":3487,"dataGaLocation":3449,"icon":3488},"back to pricing","GoBack",{"altText":3451,"config":3490},{"src":3453,"dataGaName":3454,"dataGaLocation":3449},{"altText":3451,"config":3492},{"src":3457,"dataGaName":3454,"dataGaLocation":3449},{"title":3494,"button":3495,"config":3499},"GitLab Orbit est arrivé : la couche de contexte pour les agents d'IA.",{"text":3105,"config":3496},{"href":3497,"dataGaName":3498,"dataGaLocation":3063},"/fr-fr/gitlab-orbit/","orbit",{"layout":3500,"disabled":3042},"release",{"data":3502},{"text":3503,"source":3504,"edit":3510,"contribute":3515,"config":3519,"items":3524,"minimal":3731},"Git est une marque déposée de Software Freedom Conservancy et notre utilisation de « GitLab » est sous licence.",{"text":3505,"config":3506},"Afficher le code source de la page",{"href":3507,"dataGaName":3508,"dataGaLocation":3509},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":3511,"config":3512},"Modifier cette page",{"href":3513,"dataGaName":3514,"dataGaLocation":3509},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":3295,"config":3516},{"href":3517,"dataGaName":3518,"dataGaLocation":3509},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":3520,"facebook":3521,"youtube":3522,"linkedin":3523},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[3525,3571,3623,3666,3698],{"title":3212,"links":3526,"subMenu":3541},[3527,3531,3536],{"text":3528,"config":3529},"Voir les forfaits",{"href":3214,"dataGaName":3530,"dataGaLocation":3509},"view plans",{"text":3532,"config":3533},"GitLab Premium",{"href":3534,"dataGaName":3535,"dataGaLocation":3509},"/fr-fr/pricing/premium/","why premium",{"text":3537,"config":3538},"GitLab Ultimate",{"href":3539,"dataGaName":3540,"dataGaLocation":3509},"/fr-fr/pricing/ultimate/","why ultimate",[3542],{"title":3387,"links":3543},[3544,3546,3548,3551,3556,3561,3566],{"text":3394,"config":3545},{"href":3396,"dataGaName":3073,"dataGaLocation":3509},{"text":3399,"config":3547},{"href":3401,"dataGaName":3402,"dataGaLocation":3509},{"text":3549,"config":3550},"Portail clients",{"href":3406,"dataGaName":3407,"dataGaLocation":3509},{"text":3552,"config":3553},"Statut",{"href":3554,"dataGaName":3555,"dataGaLocation":3509},"https://status.gitlab.com/","status",{"text":3557,"config":3558},"Conditions d'utilisation",{"href":3559,"dataGaName":3560,"dataGaLocation":3509},"/terms/","terms of use",{"text":3562,"config":3563},"Politique de confidentialité",{"href":3564,"dataGaName":3565,"dataGaLocation":3509},"/fr-fr/privacy/","privacy statement",{"text":3567,"config":3568},"Gestion des cookies",{"dataGaName":3569,"dataGaLocation":3509,"id":3570,"isOneTrustButton":222},"cookie preferences","ot-sdk-btn",{"title":3110,"links":3572,"subMenu":3581},[3573,3577],{"text":3574,"config":3575},"Plateforme DevSecOps",{"href":3092,"dataGaName":3576,"dataGaLocation":3509},"devsecops platform",{"text":3578,"config":3579},"Développement assisté par l'IA",{"href":3099,"dataGaName":3580,"dataGaLocation":3509},"ai-assisted development",[3582],{"title":3583,"links":3584},"Thèmes",[3585,3589,3594,3599,3604,3608,3613,3618],{"text":3130,"config":3586},{"href":3587,"dataGaName":3588,"dataGaLocation":3509},"/fr-fr/topics/ci-cd/","cicd",{"text":3590,"config":3591},"GitOps",{"href":3592,"dataGaName":3593,"dataGaLocation":3509},"/fr-fr/topics/gitops/","gitops",{"text":3595,"config":3596},"DevOps",{"href":3597,"dataGaName":3598,"dataGaLocation":3509},"/fr-fr/topics/devops/","devops",{"text":3600,"config":3601},"Contrôle de version",{"href":3602,"dataGaName":3603,"dataGaLocation":3509},"/fr-fr/topics/version-control/","version control",{"text":3055,"config":3605},{"href":3606,"dataGaName":3607,"dataGaLocation":3509},"/fr-fr/topics/devsecops/","devsecops",{"text":3609,"config":3610},"Cloud-native",{"href":3611,"dataGaName":3612,"dataGaLocation":3509},"/fr-fr/topics/cloud-native/","cloud native",{"text":3614,"config":3615},"IA pour la programmation",{"href":3616,"dataGaName":3617,"dataGaLocation":3509},"/fr-fr/topics/devops/ai-for-coding/","ai for coding",{"text":3619,"config":3620},"IA agentique",{"href":3621,"dataGaName":3622,"dataGaLocation":3509},"/fr-fr/topics/agentic-ai/","agentic ai",{"title":3624,"links":3625},"Solutions",[3626,3629,3631,3636,3639,3642,3645,3648,3650,3653,3656,3661],{"text":3155,"config":3627},{"href":3150,"dataGaName":3628,"dataGaLocation":3509},"Application Security Testing",{"text":3142,"config":3630},{"href":3126,"dataGaName":3127,"dataGaLocation":3509},{"text":3632,"config":3633},"Développement Agile",{"href":3634,"dataGaName":3635,"dataGaLocation":3509},"/fr-fr/solutions/agile-delivery/","agile delivery",{"text":3137,"config":3637},{"href":3139,"dataGaName":3638,"dataGaLocation":3509},"source code management",{"text":3130,"config":3640},{"href":3132,"dataGaName":3641,"dataGaLocation":3509},"continuous integration & delivery",{"text":3181,"config":3643},{"href":3183,"dataGaName":3644,"dataGaLocation":3509},"value stream management",{"text":3590,"config":3646},{"href":3647,"dataGaName":3593,"dataGaLocation":3509},"/fr-fr/solutions/gitops/",{"text":3194,"config":3649},{"href":3197,"dataGaName":3198,"dataGaLocation":3509},{"text":3651,"config":3652},"PME",{"href":3203,"dataGaName":3204,"dataGaLocation":3509},{"text":3654,"config":3655},"Secteur public",{"href":3209,"dataGaName":3210,"dataGaLocation":3509},{"text":3657,"config":3658},"Éducation",{"href":3659,"dataGaName":3660,"dataGaLocation":3509},"/fr-fr/solutions/education/","education",{"text":3662,"config":3663},"Services financiers",{"href":3664,"dataGaName":3665,"dataGaLocation":3509},"/fr-fr/solutions/finance/","financial services",{"title":3217,"links":3667},[3668,3670,3672,3674,3677,3679,3682,3684,3686,3688,3690,3692,3694,3696],{"text":3230,"config":3669},{"href":3232,"dataGaName":3233,"dataGaLocation":3509},{"text":3235,"config":3671},{"href":3237,"dataGaName":3238,"dataGaLocation":3509},{"text":3240,"config":3673},{"href":3242,"dataGaName":3243,"dataGaLocation":3509},{"text":3245,"config":3675},{"href":3247,"dataGaName":3676,"dataGaLocation":3509},"docs",{"text":3268,"config":3678},{"href":3270,"dataGaName":3271,"dataGaLocation":3509},{"text":3680,"config":3681},"Nouveautés",{"href":3328,"dataGaName":3329,"dataGaLocation":3509},{"text":3263,"config":3683},{"href":3265,"dataGaName":3266,"dataGaLocation":3509},{"text":3282,"config":3685},{"href":3284,"dataGaName":3285,"dataGaLocation":3509},{"text":3290,"config":3687},{"href":3292,"dataGaName":3293,"dataGaLocation":3509},{"text":3295,"config":3689},{"href":3297,"dataGaName":3298,"dataGaLocation":3509},{"text":3300,"config":3691},{"href":3302,"dataGaName":3303,"dataGaLocation":3509},{"text":3305,"config":3693},{"href":3307,"dataGaName":3308,"dataGaLocation":3509},{"text":3310,"config":3695},{"href":3312,"dataGaName":3313,"dataGaLocation":3509},{"text":3315,"config":3697},{"href":3317,"dataGaName":3318,"dataGaLocation":3509},{"title":3331,"links":3699},[3700,3702,3704,3706,3708,3710,3715,3720,3722,3724,3726],{"text":3339,"config":3701},{"href":3341,"dataGaName":3333,"dataGaLocation":3509},{"text":3344,"config":3703},{"href":3346,"dataGaName":3347,"dataGaLocation":3509},{"text":3352,"config":3705},{"href":3354,"dataGaName":3355,"dataGaLocation":3509},{"text":3357,"config":3707},{"href":3359,"dataGaName":3360,"dataGaLocation":3509},{"text":3362,"config":3709},{"href":3364,"dataGaName":3365,"dataGaLocation":3509},{"text":3711,"config":3712},"Développement durable",{"href":3713,"dataGaName":3714,"dataGaLocation":3509},"/sustainability/","Sustainability",{"text":3716,"config":3717},"Diversité, inclusion et appartenance (DIB)",{"href":3718,"dataGaName":3719,"dataGaLocation":3509},"/fr-fr/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":3367,"config":3721},{"href":3369,"dataGaName":3370,"dataGaLocation":3509},{"text":3377,"config":3723},{"href":3379,"dataGaName":3380,"dataGaLocation":3509},{"text":3382,"config":3725},{"href":3384,"dataGaName":3385,"dataGaLocation":3509},{"text":3727,"config":3728},"Déclaration de transparence sur l'esclavage moderne",{"href":3729,"dataGaName":3730,"dataGaLocation":3509},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":3732},[3733,3735,3737],{"text":3557,"config":3734},{"href":3559,"dataGaName":3560,"dataGaLocation":3509},{"text":3567,"config":3736},{"dataGaName":3569,"dataGaLocation":3509,"id":3570,"isOneTrustButton":222},{"text":3562,"config":3738},{"href":3564,"dataGaName":3565,"dataGaLocation":3509},[3740],{"id":3741,"title":7,"body":3041,"config":3742,"content":3744,"description":3041,"extension":3748,"meta":3749,"navigation":222,"path":3750,"seo":3751,"stem":3752,"__hash__":3753},"blogAuthors/en-us/blog/authors/michael-friedrich.yml",{"template":3743},"BlogAuthor",{"name":7,"config":3745},{"headshot":3746,"ctfId":3747},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659879/Blog/Author%20Headshots/dnsmichi-headshot.jpg","dnsmichi","yml",{},"/en-us/blog/authors/michael-friedrich",{},"en-us/blog/authors/michael-friedrich","lJ-nfRIhdG49Arfrxdn1Vv4UppwD51BB13S3HwIswt4",[3755,3762,3770],{"title":3756,"description":3757,"heroImage":3758,"category":3037,"date":3759,"authors":3760,"slug":3761,"externalUrl":3041},"Moderniser Java avec Cursor et GitLab","Ce tutoriel commence par la correction ciblée de tests, introduit des murs qualité et met en œuvre des modifications de code en tenant compte du contexte du cycle de développement, des tests et des preuves de revue.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1776457632/llddiylsgwuze0u1rjks.png","2026-08-12",[7],"modernize-java-with-cursor-and-gitlab",{"title":3763,"description":3764,"heroImage":3765,"category":3037,"date":3766,"authors":3767,"slug":3769,"externalUrl":3041},"Comment utiliser des agents d'IA pour migrer la limitation de débit de GitLab","Découvrez comment notre équipe composée de trois personnes a utilisé GitLab Duo Agent Platform, ainsi que d'autres outils d'IA, pour migrer avec succès le système de limitation de débit et les leçons que nous en avons tirées.","https://res.cloudinary.com/about-gitlab-com/image/upload/f_auto,q_auto,c_lfill/v1773075582/yiosxfhwk8rfkulrtchv.png","2026-08-10",[3768],"Sam Wiskow","ai-agents-for-migrating-rate-limiting-system",{"title":3771,"description":3772,"heroImage":3773,"category":3037,"date":3774,"authors":3775,"slug":3777,"externalUrl":3041},"Codage agentique : le contexte fait la différence","Les agents de codage accélèrent le développement. Grâce au contexte dans GitLab, les entreprises évitent les correctifs superficiels et raccourcissent les cycles de revue.","https://res.cloudinary.com/about-gitlab-com/image/upload/f_auto,q_auto,c_lfill/v1773856365/gsx2c0vqlswox3ldmq88.jpg","2026-08-03",[3776],"Jessica Taylor","agentic-coding-only-as-good-as-context",{"promotions":3779},[3780,3793,3805,3817],{"id":3781,"categories":3782,"header":3783,"text":3784,"button":3785,"image":3790},"ai-modernization",[3037],"L'IA tient-elle ses promesses à grande échelle ?","Le questionnaire ne prendra pas plus de 5 minutes.",{"text":3786,"config":3787},"Obtenez votre score de maturité IA",{"href":3788,"dataGaName":3789,"dataGaLocation":3271},"/fr-fr/assessments/ai-modernization-assessment/","modernization assessment",{"config":3791},{"src":3792},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":3794,"categories":3795,"header":3797,"text":3784,"button":3798,"image":3802},"devops-modernization",[3796,3607],"product","Vous contentez-vous de gérer des outils ou de livrer des innovations ?",{"text":3799,"config":3800},"Obtenez votre score de maturité DevOps",{"href":3801,"dataGaName":3789,"dataGaLocation":3271},"/fr-fr/assessments/devops-modernization-assessment/",{"config":3803},{"src":3804},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":3806,"categories":3807,"header":3809,"text":3784,"button":3810,"image":3814},"security-modernization",[3808],"security","Faut-il sacrifier la rapidité pour garantir la sécurité ?",{"text":3811,"config":3812},"Obtenez votre score de maturité en matière de sécurité",{"href":3813,"dataGaName":3789,"dataGaLocation":3271},"/fr-fr/assessments/security-modernization-assessment/",{"config":3815},{"src":3816},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":3818,"paths":3819,"header":3822,"text":3823,"button":3824,"image":3829},"github-azure-migration",[3820,3821],"migration-from-azure-devops-to-gitlab","integrating-azure-devops-scm-and-gitlab","Votre équipe est-elle prête pour la migration de GitHub vers Azure ?","GitHub a déjà commencé sa migration vers Azure. Découvrez ce que cela signifie pour vous.",{"text":3825,"config":3826},"Découvrez les différences entre GitLab et GitHub",{"href":3827,"dataGaName":3828,"dataGaLocation":3271},"/fr-fr/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":3830},{"src":3804},{"header":3832,"blurb":3833,"button":3834,"secondaryButton":3838},"Commencez à développer plus rapidement dès aujourd'hui","Découvrez ce que votre équipe peut accomplir avec la plateforme d'orchestration intelligente pour le DevSecOps.\n",{"text":3065,"config":3835},{"href":3836,"dataGaName":3068,"dataGaLocation":3837},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/fr-fr/","feature",{"text":3394,"config":3839},{"href":3396,"dataGaName":3073,"dataGaLocation":3837},1786803776972]