GitLab Duo 활용 사례
GitLab v19.5요약
다음 사용 사례는 GitLab Duo를 활용한 실용적인 예시, 연습, 워크플로를 제공합니다. GitLab Self-Managed를 사용하는 경우, 최상의 사용자 경험과 결과를 위해 GitLab Duo는 GitLab 17.2 이상이 필요합니다.
다음 사용 사례는 GitLab Duo를 활용한 실용적인 예시, 연습, 워크플로를 제공합니다. 다음 방법을 배웁니다.
- 기존 소스 코드를 리팩터링합니다.
- GitLab Duo Root Cause Analysis를 사용해 실패한 job을 문제 해결합니다.
- 보안 취약점을 해결합니다.
GitLab Self-Managed를 사용하는 경우, 최상의 사용자 경험과 결과를 위해 GitLab Duo는 GitLab 17.2 이상이 필요합니다. 이전 버전도 계속 작동할 수 있지만 경험이 저하될 수 있습니다.
GitLab Duo로 개발 과제 해결#
C# 애플리케이션으로 시작#
이 예시에서는 C# IDE를 열고 GitLab Duo가 활성화되어 있는지 확인한 다음, GitLab Duo의 AI 네이티브 기능으로 더 효율적으로 작업하는 방법을 살펴봅니다.
GitLab REST API를 조회하는 CLI 도구#
GitLab Duo Coffee Chat: Get started with C#을 시청합니다.
과제는 GitLab REST API를 조회하는 CLI 도구를 만드는 것입니다.
-
GitLab Duo Chat에 새 C# 프로젝트를 시작하는 방법을 묻고 dotNET CLI 사용법을 배웁니다.
How can I get started creating an empty C# console application in VS Code? -
새 코드 주석으로 Code Suggestions를 사용해 REST API 클라이언트를 생성합니다.
// Connect to a REST API and print the response -
생성된 소스 코드에는 설명이 필요할 수 있습니다. 코드 작업
/explain을 사용해 REST API 호출이 어떻게 동작하는지 파악합니다.
Code Suggestions 주석으로 소스 코드를 생성한 다음에는 CI/CD를 구성해야 합니다.
-
Chat은 C#용
.gitignore파일의 모범 사례를 안내할 수 있습니다.Show a .gitignore and .gitlab-ci.yml configuration for a C# project. -
CI/CD job이 실패하면 Root Cause Analysis로 실패한 CI/CD job을 문제 해결합니다. 또는 오류 메시지를 GitLab Duo Chat에 복사해 도움을 요청할 수 있습니다.
Explain the CI/CD error: The current .NET SDK does not support targeting .NET 8.0 -
나중에 테스트를 만들려면 GitLab Duo에 코드 작업
/refactor를 사용해 선택한 코드를 함수로 리팩터링하도록 요청합니다. -
Chat은 프로그래밍 언어별 키워드와 함수, 또는 C# 컴파일러 오류도 설명할 수 있습니다.
Can you explain async and await in C# with practical examples? explain error CS0122: 'Program' is inaccessible due to its protection level -
/tests코드 작업으로 테스트를 생성합니다.
다음 문제는 C# 솔루션에서 생성된 테스트를 어디에 둘지입니다. 초보자는 가져오기(import) 문제를 피하려면 애플리케이션 프로젝트와 테스트 프로젝트가 같은 솔루션 수준에 있어야 한다는 사실을 모를 수 있습니다.
-
GitLab Duo Chat에 질문하고 프롬프트를 다듬으면 도움을 받을 수 있습니다.
In C# and VS Code, how can I add a reference to a project from a test project? Provide the XML configuration which I can add to a C# .csproj file to add a reference to another project in the existing solution? -
더 나은 결과를 얻으려면 프롬프트를 다듬어야 할 때도 있습니다. 프롬프트
/refactor into the public class는 나중에 테스트 프로젝트에서 접근할 수 있는 코드 제안을 만듭니다./refactor into the public class -
/refactor코드 작업으로.gitlab-ci.yml파일에서 테스트를 실행하는 방법을 Chat에 물어볼 수도 있습니다./refactor add a job to run tests (the test project)
리소스:
C++ 애플리케이션 개선#
SQLite를 사용하는 C++ 애플리케이션 리팩터링#
이 예시에는 main 함수 하나로 이루어진 기존 소스 코드가 있습니다. 이 코드는 반복이 많고 테스트할 수 없습니다.
GitLab Duo Coffee Chat: C++, SQLite and CMake를 시청합니다.
소스 코드를 재사용 가능하고 테스트할 수 있는 함수로 리팩터링하려면 다음과 같이 합니다.
-
GitLab Duo가 활성화된 VS Code 또는 Web IDE를 엽니다.
-
소스 코드를 선택하고, 다듬은 프롬프트로 GitLab Duo Chat에 함수로 리팩터링하도록 요청합니다.
/refactor into functions이 리팩터링 단계는 선택한 소스 코드 전체에는 동작하지 않을 수 있습니다.
-
리팩터링 전략을 기능 블록으로 나눕니다. 예를 들어 데이터베이스의 모든 삽입, 업데이트, 삭제 작업을 차례로 반복합니다.
-
새로 만든 함수의 테스트를 생성하려면 소스 코드를 다시 선택하고 코드 작업
/tests를 사용합니다. 테스트 프레임워크에 대한 구체적인 지시를 프롬프트에 포함합니다./tests using the CTest test framework -
애플리케이션이
Boost.Test프레임워크를 대신 사용한다면 프롬프트를 다듬습니다./tests using the Boost.Test framework
리소스:
C++ 함수를 객체 지향 코드로 리팩터링#
이 예시에서는 기존 소스 코드가 함수로 감싸져 있습니다. 앞으로 더 많은 데이터베이스 유형을 지원하려면 코드를 클래스와 객체 상속 구조로 리팩터링해야 합니다.
이 단계를 따라가는 과정은 GitLab Duo Coffee Chat: Refactor C++ functions into OOP classes에서 시청합니다.
클래스 작업 시작#
-
GitLab Duo Chat에 기본 데이터베이스 클래스를 위한 객체 지향 패턴을 구현하고 SQLite 클래스에서 이를 상속하는 방법을 묻습니다.
Explain a generic database implementation using a base class, and SQLite specific class using C++. Provide source examples and steps to follow. -
학습 과정에는 구현 클래스의 순수 가상 함수와 가상 함수 오버라이드에 대해 GitLab Duo Chat에 묻는 일이 포함됩니다.
What is a pure virtual function, and what is required for the developer inheriting from that class? -
코드 작업은 코드 리팩터링에 도움이 됩니다. C++ 헤더 파일에서 함수를 선택하고, 다듬은 프롬프트를 사용합니다.
/refactor into class with public functions, and private path/db attributes. Inherit from the base class DB /refactor into a base class with pure virtual functions called DB. Remove the SQLite specific parts. -
GitLab Duo Chat은 생성자 오버로딩, 객체 초기화, 공유 포인터를 이용한 메모리 관리 최적화도 안내합니다.
How to add a function implementation to a class in a cpp file? How to pass values to class attributes through the class constructor call?
더 나은 답변 찾기#
-
다음 질문은 충분한 컨텍스트를 제공하지 않았습니다.
Should I use virtual override instead of just override? -
대신 컨텍스트를 더 추가해 더 나은 답변을 얻습니다.
When implementing a pure virtual function in an inherited class, should I use virtual function override, or just function override? Context is C++. -
비교적 복잡한 질문은 새로 만든 클래스에서 객체를 인스턴스화하고 특정 함수를 호출하는 방법에 관한 것입니다.
How to instantiate an object from a class in C++, call the constructor with the SQLite DB path and call the functions. Prefer pointers. -
결과가 도움이 될 수 있지만, 공유 포인터와 필요한 소스 코드 헤더에 대한 보완이 필요했습니다.
How to instantiate an object from a class in C++, call the constructor with the SQLite DB path and call the functions. Prefer shared pointers. Explain which header includes are necessary. -
Code Suggestions는
std::shared_ptr포인터 연산에 맞는 구문을 생성하고 코드 품질을 개선하는 데 도움이 됩니다.// Define the SQLite path in a variable, default value database.db // Create a shared pointer for the SQLite class // Open a database connection using OpenConnection
코드 리팩터링#
-
소스 코드를 리팩터링한 후 컴파일러 오류가 발생할 수 있습니다. Chat에 이를 설명하도록 요청합니다.
Explain the error: `db` is a private member of `SQLiteDB` -
특정 SQL 쿼리 문자열은 더 효율적으로 편집할 수 있도록 여러 줄 문자열로 리팩터링해야 합니다.
std::string sql = "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, email TEXT NOT NULL)"; -
소스 코드를 선택하고
/refactor코드 작업을 사용합니다./refactor into a stringstream with multiple lines -
유틸리티 함수를 정적 함수를 제공하는 C++ 클래스로 리팩터링한 다음, Chat에 호출 방법을 물어볼 수도 있습니다.
/refactor into a class providing static functions How to call the static functions in the class?
소스 코드를 리팩터링하면 더 많은 데이터베이스 유형을 지원할 기반이 마련되고 전반적인 코드 품질이 향상됩니다.
리소스:
Kotlin 애플리케이션 설명, 테스트, 리팩터링#
이 예시에서는 Kotlin 코드 생성 프롬프트의 어드벤처 애플리케이션을 분석하고, 리팩터링과 테스트로 개선해야 합니다.
현재 소스 코드는 다음과 같습니다.
package org.example
// Create a text adventure
// Search for the golden LEGO brick
// Add visual helpers
// Use random timer traps for game over
// Create a text adventure
fun createTextAdventure() {
println("Welcome to the golden LEGO brick adventure!")
println("You find yourself in a dimly lit room. What do you do?")
var gameOver = false
while (!gameOver) {
println("1. Search for the golden LEGO brick")
println("2. Examine the room")
println("3. Quit")
val choice = readLine()?.toIntOrNull() ?: 0
when (choice) {
1 -> searchForBrick()
2 -> examineRoom()
3 -> {
println("Goodbye!")
gameOver = true
}
else -> println("Invalid choice. Please try again.")
}
}
}
fun searchForBrick() {
println("You search the room carefully, looking for any sign of the golden LEGO brick.")
if (Math.random() < 0.2) {
println("Congratulations! You found the golden LEGO brick!")
} else {
println("Your search turns up nothing. You'll have to try again.")
}
}
fun examineRoom() {
println("You look around the room, taking in the details.")
println("The room is dimly lit, with shadows in the corners.")
println("There is a door to the north and a table in the center of the room.")
}
fun main() {
createTextAdventure()
}
-
IDE에서 소스 코드를 선택한 다음 마우스 오른쪽 버튼을 클릭해 GitLab Duo Chat이 코드를 설명하도록 합니다.
-
프롬프트를 다듬어 버그, 최적화 팁, 취약점에 대해 더 알아봅니다.
/explain focus on bugs and improvements The provided code is a simple text adventure game written in Kotlin. It allows the user to search for a golden LEGO brick or examine the room. While the code is functional, there are a few potential bugs and areas for improvement: 1. Potential Bugs: The searchForBrick() function uses Math.random() to determine if the player finds the golden LEGO brick. However, this function does not handle the case where the player finds the brick. The game will continue indefinitely, even after the player has found the brick. 2. Improvements: Game Over Condition: The game should have a proper game over condition when the player finds the golden LEGO brick. This could be achieved by introducing a boolean flag or a separate game state to track whether the brick has been found. -
/tests명령을 사용해 Chat이 선택한 코드의 테스트를 생성하도록 요청합니다./tests To test the code, you can use JUnit for Kotlin. Here are some tests you can write: import org.junit.jupiter.api.Test import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream import java.io.PrintStream class TextAdventureTest { private val standardOut = System.out private val standardIn = System.`in` @Test fun `test searchForBrick success`() { val outContent = ByteArrayOutputStream() System.setOut(PrintStream(outContent)) searchForBrick() val output = outContent.toString().trim() assert(output.contains("Congratulations! You found the golden LEGO brick!")) System.setOut(standardOut) } ... }
모든 코드가 테스트되는지 확인한 후, Chat에 선택한 코드를 리팩터링하도록 요청합니다.
/refactor fix bugs, improve UX
...
Improvements:
Extracted the menu printing logic into a separate printMenu function for better code organization and readability.
Used Random.nextDouble() instead of Math.random() for better compatibility with Kotlin's standard library.
Added a prompt for the user to enter their choice after printing the menu.
Removed the unnecessary gameOver variable initialization, as it's already assigned a value in the createTextAdventure function.
Added a comment in the searchForBrick function to remind you to add additional logic or game over condition if needed.
These changes should improve the code's readability, maintainability, and user experience.
리팩터링된 소스 코드는 다음과 같을 수 있습니다.
package org.example
import kotlin.random.Random
// Create a text adventure
// Search for the golden LEGO brick
// Add visual helpers
// Use random timer traps for game over
// Create a text adventure
fun createTextAdventure() {
println("Welcome to the golden LEGO brick adventure!")
println("You find yourself in a dimly lit room. What do you do?")
var gameOver = false
while (!gameOver) {
printMenu()
val choice = readLine()?.toIntOrNull()
when (choice) {
1 -> searchForBrick()
2 -> examineRoom()
3 -> {
println("Goodbye!")
gameOver = true
}
else -> println("Invalid choice. Please try again.")
}
}
}
fun printMenu() {
println("1. Search for the golden LEGO brick")
println("2. Examine the room")
println("3. Quit")
print("Enter your choice: ")
}
fun searchForBrick() {
println("You search the room carefully, looking for any sign of the golden LEGO brick.")
if (Random.nextDouble() < 0.2) {
println("Congratulations! You found the golden LEGO brick!")
// Add additional logic or game over condition here
} else {
println("Your search turns up nothing. You'll have to try again.")
}
}
fun examineRoom() {
println("You look around the room, taking in the details.")
println("The room is dimly lit, with shadows in the corners.")
println("There is a door to the north and a table in the center of the room.")
}
fun main() {
createTextAdventure()
}
PowerShell 시작하기#
PowerShell 지원은 실험 기능입니다.
-
GitLab Duo Chat에 현재 디렉터리의 파일 크기를 출력하는 PowerShell 스크립트를 시작하는 방법을 묻습니다.
How to get started with a PowerShell script that prints the file size of the current directory?또는 Code Suggestions로 소스 코드를 생성할 수 있습니다.
-
다음 내용으로 새 스크립트
get-file-sizes.ps1을 만듭니다.# Collect the files in a directory and print their size -
Code Suggestions가 프롬프트를 완성할 때까지 기다린 다음, 다음 프롬프트를 추가해 다양한 출력 형식을 실험합니다.
# Collect the files in a directory and print their size $directory = Read-Host -Prompt "Enter the directory path to get file sizes" $files = Get-ChildItem -Path $directory -File foreach ($file in $files) { $fileSize = [Math]::Round(($file.Length / 1KB), 2) Write-Host "$($file.Name) - $fileSize KB" } # Repeat the code above but store the results in a CSV file -
다른 내보내기 형식의 프롬프트로 단계를 반복하거나, Code Suggestions 자동 완성을 사용합니다. 예를 들면 다음과 같습니다.
# Collect the files in a directory and print their size $directory = Read-Host -Prompt "Enter the directory path to get file sizes" $files = Get-ChildItem -Path $directory -File foreach ($file in $files) { $fileSize = [Math]::Round(($file.Length / 1KB), 2) Write-Host "$($file.Name) - $fileSize KB" } # Repeat the code above but store the results in a CSV file $csvFile = "$directory\file-sizes.csv" $fileData = foreach ($file in $files) { [PSCustomObject]@{ FileName = $file.Name FileSize = [Math]::Round(($file.Length / 1KB), 2) } } $fileData | Export-Csv -Path $csvFile -NoTypeInformation Write-Host "File sizes saved to $csvFile" # Repeat the code above but store the results in a JSON file $jsonFile = "$directory\file-sizes.json" $fileData | ConvertTo-Json | Out-File -FilePath $jsonFile Write-Host "File sizes saved to $jsonFile" # Repeat the code above but store the results in a XML file $xmlFile = "$directory\file-sizes.xml" $fileData | ConvertTo-Xml -NoTypeInformation | Out-File -FilePath $xmlFile Write-Host "File sizes saved to $xmlFile" # Repeat the code above but store the results in a HTML file $htmlFile = "$directory\file-sizes.html" $fileData | ConvertTo-Html -Property FileName, FileSize | Out-File -FilePath $htmlFile Write-Host "File sizes saved to $htmlFile" # Repeat the code above but store the results in a TXT file $txtFile = "$directory\file-sizes.txt" $fileData | Out-File -FilePath $txtFile Write-Host "File sizes saved to $txtFile"
취약점 설명 및 해결#
C 코드의 취약점#
이 예시에서는 GitLab Duo의 도움을 받아 C에서 탐지된 보안 취약점을 수정합니다.
이 단계를 따라가는 과정은 GitLab Duo Coffee Chat: Vulnerability Resolution Challenge #1에서 시청합니다.
이 소스 코드 스니펫은 버퍼 오버플로 보안 취약점을 유발합니다.
strcpy(region, "Hello GitLab Duo Vulnerability Resolution challenge");
printf("Contents of region: %s\n", region);
SAST 보안 스캐너가 이 문제를 탐지하고 보고할 수 있습니다. Vulnerability Explanation을 사용해 문제를 이해합니다. Vulnerability Resolution은 MR 생성을 돕습니다. 제안된 변경 사항이 요구 사항에 맞지 않거나 문제를 일으킬 수 있다면 Code Suggestions와 Chat으로 다듬을 수 있습니다. 예를 들면 다음과 같습니다.
-
GitLab Duo가 활성화된 VS Code 또는 Web IDE를 열고, 지시 사항이 담긴 주석을 추가합니다.
// Avoid potential buffer overflows // Possible AI-generated code below strncpy(region, "Hello GitLab Duo Vulnerability Resolution challenge", pagesize); region[pagesize-1] = '\0'; printf("Contents of region: %s\n", region); -
제안된 코드를 삭제하고, 다른 주석을 사용해 대체 방법을 사용합니다.
// Avoid potential buffer overflows using snprintf() // Possible AI-generated code below snprintf(region, pagesize, "Hello GitLab Duo Vulnerability Resolution challenge"); printf("Contents of region: %s\n", region); -
GitLab Duo Chat에 질문합니다.
/refactor코드 작업은 다양한 제안을 생성할 수 있습니다. 특정 알고리즘이나 함수를 선호한다면 프롬프트를 다듬습니다./refactor using snprintf
리소스:
GitLab 관련 질문에 답변#
이 예시의 과제는 GitLab Duo Chat으로 문제를 해결하는 것입니다.
이 단계를 따라가는 과정은 GitLab Duo Coffee Chat: Solve problems with GitLab Duo Chat Challenge에서 시청합니다.
-
GitLab Duo Chat으로 CI/CD 오류를 설명할 수 있습니다.
Explain this CI/CD error: build.sh: line 14: go command not found -
성급하게 한두 단어만 입력하는 경우에 어떤 일이 일어나는지 살펴봅니다.
labels issue labelsGitLab Duo Chat이 컨텍스트를 더 요청합니다.
-
질문을 문제를 설명하고 해결책을 묻는 완전한 문장으로 다듬습니다.
Explain labels in GitLab. Provide an example for efficient usage.
리소스:
Root Cause Analysis 사용 사례#
Root Cause Analysis를 사용해 CI/CD job 실패의 근본 원인을 파악합니다. 다음 예시는 흔한 오류를 보여 주며, 프로젝트를 포크해 근본 원인을 찾아 수정하는 연습을 해 보도록 권장합니다.
자세한 내용은 블로그 게시물 Developing GitLab Duo: Blending AI and Root Cause Analysis to fix CI/CD pipelines를 참고합니다.
Go 런타임 누락 분석#
CI/CD job은 지정한 image
속성으로 생성된 컨테이너에서 실행될 수 있습니다. 컨테이너에 프로그래밍 언어 런타임이 없으면
go 바이너리를 참조하는 script 섹션이 실패합니다. 예를 들어
오류 메시지 /bin/sh: eval: line 149: go: not found의 의미를 파악하고
수정해야 합니다. 컨테이너의 런타임 컨텍스트에서 go 명령을 찾을 수 없다면
여러 이유가 있을 수 있습니다.
- job이
alpine같은 최소 컨테이너 이미지를 사용하며, Go 언어 런타임이 설치되지 않았습니다. - job이 CI/CD 구성에 지정된 잘못된 기본 컨테이너 이미지를 사용하거나,
default키워드를 사용합니다. - job이 컨테이너 이미지 대신 셸 executor를 사용합니다. 호스트 운영 체제가 손상되었거나, Go 언어 런타임이 설치되어 있지 않거나, 구성되지 않았습니다.
프로젝트 Challenge: Root Cause Analysis - Go GitLab Release Fetcher는
Go Tanuki 앱으로 CI/CD 문제를 분석하고 수정하는 연습을 제공합니다. 이 연습에서는
build job과 docker-build job이 실패합니다. 문제를 수정하면
CI/CD 파이프라인이 성공하고 build job이 출력을 표시합니다.
solution/ 디렉터리에는 가능한 해결 방법 두 가지가 있습니다.
GitLab Duo로 GitLab에 기여#
GitLab Duo 사용은 GitLab 코드베이스에 기여하는 일과, 고객이 더 효율적으로 기여할 수 있는 방법에 초점을 맞춥니다.
GitLab 코드베이스는 규모가 크며, 때로는 복잡한 알고리즘이나 애플리케이션별 구현을 이해해야 합니다.
프론트엔드 기여: Profile Settings#
이 예시의 과제는 GitLab 프로필 페이지를 업데이트하고 소셜 네트워크 설정을 개선하는 것입니다.
녹화본은 여기에서 시청합니다: GitLab Duo Coffee Chat: Contribute to GitLab using Code Suggestions and Chat
GitLab Duo Chat으로 코드를 설명하고 리팩터링하며 테스트를 생성할 수 있습니다. Code Suggestions는 기존 코드를 완성하는 데 도움이 되며, Ruby, Go, VueJS로 새 함수와 알고리즘을 생성할 수 있습니다.
/explain코드 작업으로 선택한 코드 섹션을 설명하고, HAML 템플릿의 동작 방식을 배웁니다.- 코드 작업 프롬프트를 다듬어
/explain how HAML rendering works를 대신 요청할 수 있습니다.
또는 다음과 같이 채팅 프롬프트에 직접 입력할 수 있습니다.
how to populate a select in haml
리팩터링 예시는 다음과 같습니다.
/refactor into a HAML dropdown- 기존 UI 폼 코드를 살펴본 후, 프롬프트를
/refactor into a HAML dropdown with a form select로 다듬습니다.
GitLab Duo Chat은 오류 메시지 앞에 접두사를 붙여 오류를 디버깅하는 데 도움이 되었습니다.
Explain this error: undefined method `icon` for
코드 생성 프롬프트#
다음 예시는 GitLab Duo의 지원되는 언어에 대한 코드 생성 프롬프트를 제공합니다. 여러 줄 주석으로 코드 생성 프롬프트를 다듬을 수 있습니다.
이 예시는 Developer Relations 팀이 관리하는 GitLab Duo Prompts 프로젝트에 저장되어 있습니다. 이 예시는 동작을 테스트한 것입니다. 사용 환경에 맞게 검토하고 조정해야 합니다.
C 코드 생성 프롬프트#
I/O, 성능, 디스크 사용량, TCP 지연 시간을 수집하고 그 출력을 표시하는 Linux 통계 도구를 만듭니다. 전체 예시는 블로그 게시물 Top tips for efficient AI-powered Code Suggestions with GitLab Duo blog post를 참고합니다.
// Create a Linux statistic tool
// Collect IO, performance, disk usage, TCP latency
// Print summaries
// Import required headers
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <math.h>
#include <sys/statfs.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
int main() {
struct stat statbuf;
if (stat("/etc", &statbuf) != 0) {
perror("stat");
return 1;
}
printf("IO Block Size: %ld\n", statbuf.st_blksize);
// TODO: add CPU usage, disk usage, network latency measurements
AI가 생성한 소스 코드 예시는 GitLab Duo Prompts 프로젝트의 c 디렉터리에서 볼 수 있습니다.
C++ 코드 생성 프롬프트#
HTTP 클라이언트로 동작하는 CLI 애플리케이션을 만듭니다.
// Create a CLI app as HTTP client
// Create a main function
// Include all headers
// Read program options: URL, API endpoint, basic auth
#include <iostream>
#include <curl/curl.h>
#include <string>
int main(int argc, char** argv) {
std::string url;
std::string endpoint;
std::string username;
std::string password;
// Parse command line options
// ...
CURL* curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
// Set up basic auth
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_easy_setopt(curl, CURLOPT_USERPWD, (username + ":" + password).c_str());
CURLcode res = curl_easy_perform(curl);
if(res != CURLE_OK) {
std::cerr << "Request failed: " << curl_easy_strerror(res) << std::endl;
}
curl_easy_cleanup(curl);
}
return 0;
}
분산 파일 노드를 관리하는 애플리케이션을 만듭니다.
// Create an application to manage distributed file nodes
// Provide an overview the health state of nodes
// Use OOP patterns to define the base file node
// Add specific filesystems inherited from the base file
class FileNode {
public:
std::string name;
std::string ipAddress;
int port;
HealthState healthState;
FileNode(std::string name, std::string ipAddress, int port)
: name(name), ipAddress(ipAddress), port(port), healthState(HealthState::Healthy) {}
void setHealthState(HealthState state) {
healthState = state;
}
};
class LocalFileNode : public FileNode {
public:
std::string mountPoint;
LocalFileNode(std::string name, std::string mountPoint)
: FileNode(name, "127.0.0.1", 0), mountPoint(mountPoint) {}
};
class NetworkFileNode : public FileNode {
public:
std::string user;
std::string password;
NetworkFileNode(std::string name, std::string ipAddress, int port, std::string user, std::string password)
: FileNode(name, ipAddress, port), user(user), password(password) {}
};
int main(){
}
XDP 커널 이벤트에 연결해 네트워크 트래픽을 측정하는 eBPF 프로그램을 만듭니다.
Linux 커널에서만 동작합니다.
// Create an eBPF program which attaches to XDP kernel events
// Count all packets by IP address
// Print a summary
// Include necessary headers
#include <bpf/bpf.h>
struct data {
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
__type(key, uint32_t);
__type(value, uint64_t);
};
BPF_TABLE("array", int, long, counts, 1024);
int xdp_prog(struct xdp_md *ctx) {
void* data_end = (void*)(long)ctx->data_end;
void* data = (void*)(long)ctx->data;
struct ethhdr *eth = data;
if ((void*)eth + sizeof(*eth) <= data_end) {
struct iphdr *ip = data + sizeof(*eth);
if ((void*)ip + sizeof(*ip) <= data_end) {
counts.increment(ip->saddr);
}
}
return XDP_PASS;
}
AI가 생성한 소스 코드 예시는 GitLab Duo Prompts 프로젝트의 c++ 디렉터리에서 볼 수 있습니다.
C# 코드 생성 프롬프트#
여러 센서에서 데이터를 수집해 MSSQL에 저장하는 의료 분석기 앱을 만듭니다.
// Create a medical analyzer app
// Collect data from different sensors
// Store data in MSSQL
// Provide methods to access the sensor data
using System.Data.SqlClient;
namespace MedicalAnalyzer
{
public class SensorDataStore
{
private SqlConnection connection;
public SensorDataStore()
{
// Create SQL Server connection
connection = new SqlConnection("connection string here");
}
public void StoreSensorData(SensorData data)
{
// Open connection
connection.Open();
// Insert sensor data into database
var command = connection.CreateCommand();
command.CommandText = "INSERT INTO SensorData (Timestamp, DeviceId, Value) " +
"VALUES (@timestamp, @deviceId, @value)";
command.Parameters.AddWithValue("@timestamp", data.Timestamp);
command.Parameters.AddWithValue("@deviceId", data.DeviceId);
command.Parameters.AddWithValue("@value", data.Value);
command.ExecuteNonQuery();
// Close connection
connection.Close();
}
public SensorData[] GetSensorData(DateTime startTime, DateTime endTime)
{
// Query database and return results
}
}
}
AI가 생성한 소스 코드 예시는 GitLab Duo Prompts 프로젝트의 c# 디렉터리에서 볼 수 있습니다.
CSS 코드 생성 프롬프트#
/* Create CSS classes for animating a rainbow */
@keyframes rainbow {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
.rainbow {
background: linear-gradient(to right, #ff0000, #ff7700, #ffff00, #00ff00, #0000ff, #8b00ff);
background-size: 600% 600%;
animation: rainbow 30s ease infinite;
}
AI가 생성한 소스 코드 예시는 GitLab Duo Prompts 프로젝트의 css 디렉터리에서 볼 수 있습니다.
Go 코드 생성 프롬프트#
클러스터의 컨테이너, 파드, 서비스 상태를 읽고 출력하는 Kubernetes 관측 애플리케이션을 만듭니다.
// Create a client for Kubernetes observability
// Create a function that
// Reads the kubernetes configuration file from the KUBECONFIG env var
// Create kubernetes context, namespace default
// Inspect container, pod, service status and print an overview
// Import necessary packages
// Create main package
package main
import (
"context"
"fmt"
"os"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func main() {
clientset := getClientset()
namespace := "default"
printPods(clientset, namespace)
printServices(clientset, namespace)
printContainers(clientset, namespace)
}
func getClientset() *kubernetes.Clientset {
kubeconfig := os.Getenv("KUBECONFIG")
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
if err != nil {
panic(err)
}
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err)
}
return clientset
}
func printPods(clientset *kubernetes.Clientset, namespace string) {
pods, err := clientset.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
panic(err)
}
fmt.Printf("There are %d pods in the %s namespace\n", len(pods.Items), namespace)
}
func printServices(clientset *kubernetes.Clientset, namespace string) {
services, err := clientset.CoreV1().Services(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
panic(err)
}
fmt.Printf("There are %d services in the %s namespace\n", len(services.Items), namespace)
}
// Create a function to print Containers
// Collect and print the count
func printContainers(clientset *kubernetes.Clientset, namespace string) {
pods, err := clientset.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
panic(err)
}
var totalContainers int
for _, pod := range pods.Items {
totalContainers += len(pod.Spec.Containers)
}
fmt.Printf("There are %d containers in the %s namespace\n", totalContainers, namespace)
}
녹화본은 여기에서 시청합니다: GitLab Duo Coffee Chat: Code Generation Challenge with Go and Kubernetes Observability
Redis와 유사한 인메모리 키-값 저장소를 만듭니다. 전체 과정은 블로그 게시물 Top tips for efficient AI-powered Code Suggestions with GitLab Duo 를 참고합니다.
// Create an in-memory key value store, similar to Redis
// Provide methods to
// set/unset keys
// update values
// list/print with filters
// Use BoltDB as external library
AI가 생성한 소스 코드 예시는 GitLab Duo Prompts 프로젝트의 go 디렉터리에서 볼 수 있습니다.
Java 코드 생성 프롬프트#
메트릭을 위한 여러 데이터 원본을 갖춘 데이터 분석 애플리케이션을 만듭니다. 데이터 쿼리와 집계를 위한 API를 제공합니다.
// Create a data analytics app
// Parse different input sources and their values
// Store the metrics in a columnar format
// Provide an API to query and aggregate data
AI가 생성한 소스 코드 예시는 GitLab Duo Prompts 프로젝트의 java 디렉터리에서 볼 수 있습니다.
JavaScript 코드 생성 프롬프트#
날짜-시간 선택기를 포함해 ReactJS로 직원용 유급 휴가 애플리케이션을 만듭니다.
// Create a Paid Time Off app for users
// Create a date-time picker in ReactJS
// Provide start and end options
// Show public holidays based on the selected country
// Send the request to a server API
AI가 생성한 소스 코드 예시는 GitLab Duo Prompts 프로젝트의 javascript 디렉터리에서 볼 수 있습니다.
HTML 코드 생성 프롬프트#
<!-- Create an AI knowledge base.
Describe where AI can help with efficient DevSecOps workflows.
Add a table with one Dev, one Ops, one Sec example.
-->
<table>
<tr>
<th>Dev</th>
<th>Ops</th>
<th>Sec</th>
</tr>
<tr>
<td>Automated testing and continuous integration</td>
<td>Infrastructure as code and automated provisioning</td>
<td>Static code analysis and vulnerability scanning</td>
</tr>
</table>
AI가 생성한 소스 코드 예시는 GitLab Duo Prompts 프로젝트의 html 디렉터리에서 볼 수 있습니다.
Kotlin 코드 생성 프롬프트#
텍스트 어드벤처를 생성하고 보물을 찾습니다. 시각적 도우미를 추가하고 무작위 타이머 함정으로 게임 오버를 처리합니다.
package org.example
// Create a text adventure
// Search for the golden LEGO brick
// Add visual helpers
// Use random timer traps for game over
// Create a text adventure
fun createTextAdventure() {
println("Welcome to the golden LEGO brick adventure!")
println("You find yourself in a dimly lit room. What do you do?")
var gameOver = false
while (!gameOver) {
println("1. Search for the golden LEGO brick")
println("2. Examine the room")
println("3. Quit")
val choice = readLine()?.toIntOrNull() ?: 0
when (choice) {
1 -> searchForBrick()
2 -> examineRoom()
3 -> {
println("Goodbye!")
gameOver = true
}
else -> println("Invalid choice. Please try again.")
}
}
}
fun searchForBrick() {
println("You search the room carefully, looking for any sign of the golden LEGO brick.")
if (Math.random() < 0.2) {
println("Congratulations! You found the golden LEGO brick!")
} else {
println("Your search turns up nothing. You'll have to try again.")
}
}
fun examineRoom() {
println("You look around the room, taking in the details.")
println("The room is dimly lit, with shadows in the corners.")
println("There is a door to the north and a table in the center of the room.")
}
fun main() {
createTextAdventure()
}
AI가 생성한 소스 코드 예시는 GitLab Duo Prompts 프로젝트의 kotlin 디렉터리에서 볼 수 있습니다.
PHP 코드 생성 프롬프트#
GitLab 릴리스용 RSS 피드 수집기를 만들고, 제목으로 필터링할 수 있게 합니다.
// Create a web form to show GitLab releases
// Fetch the RSS feed from https://about.gitlab.com/atom.xml
// Provide filter options for the title
$feedUrl = 'https://about.gitlab.com/atom.xml';
$xml = simplexml_load_file($feedUrl);
$titleFilter = $_GET['titleFilter'];
echo '<h1>GitLab Releases</h1>';
echo '<ul>';
foreach ($xml->entry as $entry) {
$title = $entry->title;
if (empty($titleFilter) || strpos($title, $titleFilter) !== false) {
echo '<li>' . $title . '</li>';
}
}
echo '</ul>';
AI가 생성한 소스 코드 예시는 GitLab Duo Prompts 프로젝트의 php 디렉터리에서 볼 수 있습니다.
PowerShell 코드 생성 프롬프트#
디렉터리의 모든 파일을 수집하고 파일 크기를 출력하는 스크립트를 만듭니다. 프롬프트를 다듬어 결과를 CSV 또는 JSON 파일에 저장합니다.
# Collect the files in a directory and print their size
$directory = Read-Host -Prompt "Enter the directory path to get file sizes"
$files = Get-ChildItem -Path $directory -File
foreach ($file in $files) {
$fileSize = [Math]::Round(($file.Length / 1KB), 2)
Write-Host "$($file.Name) - $fileSize KB"
}
# Repeat the code above but store the results in a CSV file
$csvFile = "$directory\file-sizes.csv"
$fileData = foreach ($file in $files) {
[PSCustomObject]@{
FileName = $file.Name
FileSize = [Math]::Round(($file.Length / 1KB), 2)
}
}
$fileData | Export-Csv -Path $csvFile -NoTypeInformation
Write-Host "File sizes saved to $csvFile"
# Repeat the code above but store the results in a JSON file
$jsonFile = "$directory\file-sizes.json"
$fileData | ConvertTo-Json | Out-File -FilePath $jsonFile
Write-Host "File sizes saved to $jsonFile"
AI가 생성한 소스 코드 예시는 GitLab Duo Prompts 프로젝트의 powershell 디렉터리에서 볼 수 있습니다.
Python 코드 생성 프롬프트#
Flask로 웹 서버를 만들어 REST API로 사용자를 관리하고, SQLite에 저장합니다.
# Create a Flask webserver
# Add REST API entrypoints to manage users by ID
# Implement create, update, delete functions
# User data needs to be stored in SQlite, create table if not exists
# Run the server on port 8080, support TLS
# Print required packages for requirements.txt in a comment.
# Use Python 3.10 as default
# Potential AI-generated code below
import flask
from flask import request
import sqlite3
app = flask.Flask(__name__)
# Create SQLite database and users table if not exists
conn = sqlite3.connect('users.db')
conn.execute('''CREATE TABLE IF NOT EXISTS users
(id INTEGER PRIMARY KEY, name TEXT, email TEXT)''')
@app.route('/users', methods=['POST'])
def create_user():
# Get user data from request
name = request.form['name']
email = request.form['email']
# Insert user into database
conn.execute('INSERT INTO users (name, email) VALUES (?, ?)', (name, email))
return 'User created successfully'
@app.route('/users/<int:id>', methods=['PUT'])
def update_user(id):
# Get user data from request
name = request.form['name']
email = request.form['email']
# Update user in database
conn.execute('UPDATE users SET name = ?, email = ? WHERE id = ?', (name, email, id))
return 'User updated successfully'
@app.route('/users/<int:id>', methods=['DELETE'])
def delete_user(id):
# Delete user from database
conn.execute('DELETE FROM users WHERE id = ?', (id,))
return 'User deleted successfully'
if __name__ == '__main__':
# Required packages - flask, sqlite3
app.run(host='0.0.0.0', port=8080, ssl_context='adhoc')
AI가 생성한 소스 코드 예시는 GitLab Duo Prompts 프로젝트의 python 디렉터리에서 볼 수 있습니다.
Ruby 코드 생성 프롬프트#
로그 데이터를 Elasticsearch에 저장하는 로그 파서 애플리케이션을 만듭니다.
# Create a Ruby app as log parser
# Provide hooks to replace sensitive strings in log lines
# Format the logs and store them in Elasticsearch
# Potential AI-generated code below
require 'logger'
require 'elasticsearch'
class LogParser
attr_reader :logger
def initialize
@logger = Logger.new(STDOUT)
@elasticsearch = Elasticsearch::Client.new
end
def parse_and_store(logs)
sanitized_logs = sanitize_logs(logs)
formatted_logs = format_logs(sanitized_logs)
store_in_elasticsearch(formatted_logs)
end
private
def sanitize_logs(logs)
logs.map { |line| sanitize_line(line) }
end
def sanitize_line(line)
# replace sensitive data
line.gsub(/\d{16}/, '[REDACTED]')
end
def format_logs(logs)
logs.map { |line| "#{Time.now}: #{line}" }
end
def store_in_elasticsearch(logs)
logs.each { |log| @elasticsearch.index(index: 'app-logs', document: log) }
end
end
심각도 수준, 애플리케이션 이름, 메시지 문자열이 포함된 syslog 형식을 지원하는 로그 클라이언트 유틸리티 클래스를 만듭니다.
# Create Logging utility class
# Define default log level as attribute
# Add method for logging, inputs: level, app, message
# Print the data with formatted date and time in syslog format
# Potential AI-generated code below
class Logging
attr_accessor :log_level
def log(level, app, message)
time = Time.now.strftime("%b %d %H:%M:%S")
puts "#{time} #{app}[#{Process.pid}]: #{level} - #{message}"
end
end
# Instantiate class and test the log method
# Potential AI-generated code below
logger = Logging.new
logger.log_level = :debug
logger.log(:info, 'MyApp', 'Application started - info')
logger.log(:debug, 'MyApp', 'Application started - debug')
logger.log(:error, 'MyApp', 'Application started - error')
logger.log(:fatal, 'MyApp', 'Application started - fatal')
logger.log(:warn, 'MyApp', 'Application started - warn')
AI가 생성한 소스 코드 예시는 GitLab Duo Prompts 프로젝트의 ruby 디렉터리에서 볼 수 있습니다.
Rust 코드 생성 프롬프트#
// Query the GitLab REST API
// Get all open merge requests for gitlab-org/gitlab
use serde_json::Value;
fn main() {
let client = reqwest::blocking::Client::new();
let url = "https://gitlab.com/api/v4/projects/278964/merge_requests?state=opened";
let response = client.get(url).send().unwrap().text().unwrap();
let json: Value = serde_json::from_str(&response).unwrap();
// TODO: Pagination, default fetch results: 20
// Read the response headers to access the next page
println!("{}", json.to_string());
for mr in json.as_array().unwrap() {
println!("{} - URL: {}", mr["title"], mr["web_url"]);
}
}
RSS 피드 리더 앱을 만듭니다. 예시는 블로그 게시물 Learn advanced Rust programming with a little help from AI에서 가져왔습니다.
// Create a function that iterates over the source array
// and fetches the data using HTTP from the RSS feed items.
// Store the results in a new hash map.
// Print the hash map to the terminal.
AI가 생성한 소스 코드 예시는 GitLab Duo Prompts 프로젝트의 rust 디렉터리에서 볼 수 있습니다.
Scala 코드 생성 프롬프트#
// Implement Newtons Method
// Create an object with a main function
// Add a function that implements Newtons method for solving equations
// Add a driver function which tests the implemented function
object NewtonsMethod {
def solveEquation(f: Double => Double, df: Double => Double, x0: Double, tolerance: Double): Double = {
var x = x0
var error = Double.PositiveInfinity
while (math.abs(error) > tolerance) {
error = f(x) / df(x)
x -= error
}
x
}
def main(args: Array[String]): Unit = {
val f: Double => Double = x => x * x - 4
val df: Double => Double = x => 2 * x
val x0 = 3.0
val tolerance = 1e-6
val root = solveEquation(f, df, x0, tolerance)
println(s"The root is: $root")
}
}
AI가 생성한 소스 코드 예시는 GitLab Duo Prompts 프로젝트의 scala 디렉터리에서 볼 수 있습니다.
셸 스크립트 코드 생성 프롬프트#
CPU, 메모리, 디스크 I/O 사용량 기준 상위 10개 프로세스를 표시하는 스크립트 mytop.sh를 만듭니다.
첫 번째 코드 주석으로 시작하고, 나머지는 모두 Code Suggestions가 생성하도록 합니다.
#!/bin/bash
# Get the top 10 processes by CPU usage
top -b -n 1 | head -n 11 | awk '{print $1, $2, $3, $9}' | column -t
# Get the top 10 processes by memory usage
top -b -n 1 | head -n 11 | awk '{print $1, $2, $4, $6}' | column -t
# Get the top 10 processes by disk I/O
top -b -n 1 | head -n 11 | awk '{print $1, $2, $7, $8}' | column -t
# Get the top 10 processes by network I/O
top -b -n 1 | head -n 11 | awk '{print $1, $2, $10, $11}' | column -t
AI가 생성한 소스 코드 예시는 GitLab Duo Prompts 프로젝트의 shell 디렉터리에서 볼 수 있습니다.
TypeScript 코드 생성 프롬프트#
IPv6 및 IPv4 주소 형식을 파싱하는 유틸리티 함수를 만듭니다.
"use strict";
// Generate a TypeScript function which parses IPv6 and IPv4 address formats
// Use regular expressions
function parseAddress(address) {
const ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;
const ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
if (ipv6Regex.test(address)) {
return {
ipVersion: 6,
address
};
}
else if (ipv4Regex.test(address)) {
return {
ipVersion: 4,
address
};
}
else {
throw new Error('Invalid IP address');
}
}
// Test the function with random inputs
const testInputs = [
'2001:0db8:85a3:0000:0000:8a2e:0370:7334',
'192.168.0.1',
'not-an-ip'
];
for (const input of testInputs) {
try {
const result = parseAddress(input);
console.log(result);
}
catch (error) {
console.error(`Invalid address: ${input}`);
}
}
AI가 생성한 소스 코드 예시는 GitLab Duo Prompts 프로젝트의 typescript 디렉터리에서 볼 수 있습니다.
리소스#
많은 사용 사례가 GitLab Duo Coffee Chat YouTube 재생 목록에서 실습 녹화본으로 제공됩니다.
블로그 리소스#
다음 블로그 게시물은 이 사용 사례에 대한 튜토리얼을 제공합니다.
- Top tips for efficient AI-powered Code Suggestions with GitLab Duo
- 10 best practices for using AI-powered GitLab Duo Chat
- GitLab Duo Chat 101: Get more done on GitLab with our AI assistant
- Developing GitLab Duo: How we are dogfooding our AI features
- Developing GitLab Duo: Secure and thoroughly test AI-generated code
- Developing GitLab Duo: Blending AI and Root Cause Analysis to fix CI/CD pipelines
- Developing GitLab Duo: AI Impact analytics dashboard measures the ROI of AI
Code Suggestions 튜토리얼 블로그 게시물은 다음 언어에 대해 제공됩니다.