GitLab Duo 사용 사례

다음 사용 사례는 GitLab Duo와 함께하는 실제 예제, 연습 및 워크플로를 제공합니다.

어떻게 사용하는지 알아보세요:

  • 기존 소스 코드를 리팩토링합니다.

  • GitLab Duo Root Cause Analysis를 사용하여 문제를 디버깅합니다.

  • 보안 취 vulnerabilities를 해결합니다.

note
자체 관리형 GitLab이 있는 경우: GitLab Duo는 최상의 사용자 경험과 결과를 위해 GitLab 17.2 이상이 필요합니다. 이전 버전도 계속 작동할 수 있지만, 경험이 저하될 수 있습니다.

GitLab Duo를 사용하여 개발 문제 해결

C# 애플리케이션으로 시작하기

이 예제에서는 C# IDE를 열고, GitLab Duo가 활성화되어 있는지 확인한 후, 효율성을 높이기 위해 GitLab Duo AI 기반 기능을 사용하는 방법을 탐색합니다.

GitLab REST API 쿼리를 위한 CLI 도구

GitLab Duo 커피 챗: C#으로 시작하기를 시청하세요.

과제는 GitLab REST API 쿼리를 위한 CLI 도구를 만드는 것입니다.

  • GitLab Duo Chat에 새로운 C# 프로젝트를 시작하는 방법을 질문하고 dotNET CLI 사용 방법을 배워보세요:

    VS Code에서 빈 C# 콘솔 애플리케이션을 만드는 방법은 무엇인가요?
    
  • 새로운 코드 주석으로 REST API 클라이언트를 생성하기 위해 코드 제안(Code Suggestions)을 사용합니다:

    // REST API에 연결하고 응답을 출력합니다.
    
  • 생성된 소스 코드는 설명이 필요할 수 있습니다: 코드 작업 /explain을 사용하여 REST API 호출이 작동하는 방법에 대한 통찰력을 얻습니다.

코드 제안 주석에서 소스 코드가 생성된 후, CI/CD를 구성해야 합니다.

  • Chat은 C#에 대한 .gitignore 파일의 모범 사례에 도움을 줄 수 있습니다:

    C# 프로젝트를 위한 .gitignore 및 .gitlab-ci.yml 구성을 보여주세요.
    
  • CI/CD 작업이 실패한 경우, root cause analysis를 사용하여 실패한 CI/CD 작업을 해결합니다.

    또는 오류 메시지를 GitLab Duo Chat에 복사하고 도움을 요청할 수 있습니다:

    CI/CD 오류를 설명해 주세요: 현재 .NET SDK는 .NET 8.0을 타겟팅하는 것을 지원하지 않습니다.
    
  • 나중에 테스트를 생성하려면 GitLab Duo에 코드 작업 /refactor를 사용하여 선택한 코드를 함수로 리팩토링하도록 요청하세요.

  • Chat은 프로그래밍 언어별 키워드 및 기능, 또는 C# 컴파일러 오류를 설명할 수 있습니다.

    C#에서 async와 await를 실제 예제와 함께 설명해 주시겠어요?
    
    오류 CS0122: 'Program'은 보호 수준으로 인해 접근할 수 없습니다.
    
  • /tests 코드 작업을 사용하여 테스트를 생성합니다.

다음 질문은 C# 솔루션에서 생성된 테스트를 어디에 배치할지를 결정하는 것입니다.

초보자로서 애플리케이션과 테스트 프로젝트가 같은 솔루션 수준에 존재해야 가져오기 문제를 피할 수 있다는 것을 모를 수 있습니다.

  • GitLab Duo Chat은 질문을 요청하고 세분화하여 도와줄 수 있습니다:

    C#와 VS Code에서 테스트 프로젝트에서 프로젝트에 대한 참조를 추가하려면 어떻게 해야 합니까?
    
    기존 솔루션에서 다른 프로젝트에 대한 참조를 추가하기 위해 C# .csproj 파일에 추가할 수 있는 XML 구성을 제공해 주세요.
    
  • 때때로 더 나은 결과를 얻기 위해 프롬프트를 세분화해야 합니다. 프롬프트 /refactor into the public class는 나중에 테스트 프로젝트에서 접근할 수 있는 코드 제안을 만듭니다.

    /refactor into the public class
    
  • 또한 /refactor 코드 작업을 사용하여 Chat에 .gitlab-ci.yml 파일에서 테스트를 실행하는 방법을 문의할 수 있습니다.

    /refactor add a job to run tests (the test project)
    

리소스:

C++ 애플리케이션 개선하기

SQLite로 C++ 애플리케이션 리팩토링하기

이 예제에서는 단일 메인 함수가 있는 기존 소스 코드가 존재합니다. 이 코드는 반복적인 코드를 포함하고 있으며 테스트할 수 없습니다.


GitLab Duo Coffee Chat: C++, SQLite 및 CMake를 시청하세요.

소스 코드를 재사용 가능하고 테스트 가능 함수로 리팩토링하려면:

  1. GitLab Duo가 활성화된 VS Code 또는 웹 IDE를 엽니다.

  2. 소스 코드를 선택하고 GitLab Duo Chat에 함수를 리팩토링하도록 요청하기 위해 세련된 프롬프트를 사용합니다:

    /refactor into functions
    

    이 리팩토링 단계는 선택한 전체 소스 코드에 대해 작동하지 않을 수 있습니다.

  3. 리팩토링 전략을 기능 블록으로 나눕니다.
    예를 들어, 데이터베이스의 모든 삽입, 업데이트 및 삭제 작업을 반복합니다.

  4. 새로 생성된 함수에 대한 테스트를 생성하려면 소스 코드를 다시 선택하고 /tests 코드 작업을 사용합니다.
    테스트 프레임워크에 대한 특정 프롬프트의 지침을 포함합니다:

    /tests using the CTest test framework
    
  5. 애플리케이션이 Boost.Test 프레임워크를 대신 사용하는 경우, 프롬프트를 세련되게 수정합니다:

    /tests using the Boost.Test framework
    

리소스:

C++ 함수를 객체 지향 코드로 리팩토링하기

이 예제에서는 기존 소스 코드가 함수로 감싸져 있습니다.
앞으로 더 많은 데이터베이스 유형을 지원하려면 코드를 클래스로 리팩토링하고 객체 상속을 적용해야 합니다.


GitLab Duo Coffee Chat: C++ 함수를 OOP 클래스로 리팩토링하는 단계 시청하기

클래스 작업 시작하기
  • 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. Remote 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.
    
  • 코드 제안은 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에게 설명해 달라고 요청하세요.

    오류 설명: `db``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
    
    클래스의 정적 함수를 호출하는 방법은?
    

소스 코드를 리팩토링한 후 더 많은 데이터베이스 유형을 위한 기초가 구축되고 전반적인 코드 품질이 향상됩니다.

리소스:

Kotlin 애플리케이션 설명, 테스트 및 리팩토링

이 예제에서는 Kotlin 코드 생성 프롬프트에서의 모험 애플리케이션을 분석하고 리팩토링 및 테스트를 통해 개선해야 합니다.

현재 소스 코드는 다음과 같습니다:

package org.example

// 텍스트 모험 만들기
// 금색 LEGO砖 찾기
// 시각적 도우미 추가
// 게임 오버를 위한 랜덤 타이머 덫 사용
// 텍스트 모험 만들기
fun createTextAdventure() {
    println("금색 LEGO砖 모험에 오신 것을 환영합니다!")
    println("어두운 방에 놓인 자신을 발견했습니다. 무엇을 하시겠습니까?")

    var gameOver = false
    while (!gameOver) {
        println("1. 금색 LEGO砖 찾기")
        println("2. 방 조사하기")
        println("3. 종료")

        val choice = readLine()?.toIntOrNull() ?: 0
        when (choice) {
            1 -> searchForBrick()
            2 -> examineRoom()
            3 -> {
                println("안녕히 가세요!")
                gameOver = true
            }
            else -> println("유효하지 않은 선택입니다. 다시 시도하세요.")
        }
    }
}

fun searchForBrick() {
    println("금색 LEGO砖의 흔적을 찾기 위해 방을 조심스럽게 수색합니다.")
    if (Math.random() < 0.2) {
        println("축하합니다! 금색 LEGO砖을 찾았습니다!")
    } else {
        println("검색 결과가 없습니다. 다시 시도해야 합니다.")
    }
}

fun examineRoom() {
    println("방을 둘러보며 세부 사항을 살펴봅니다.")
    println("방은 어둡고 모서리에 그림자가 있습니다.")
    println("북쪽에는 문이 있고 방 중앙에 테이블이 있습니다.")
}

fun main() {
    createTextAdventure()
}
  1. IDE에서 소스 코드를 선택한 다음 마우스 오른쪽 버튼을 클릭하여 Duo Chat에게 코드를 설명하게 합니다.

  2. 버그, 최적화 팁 또는 취약성에 대해 더 배우기 위해 프롬프트를 수정합니다:

    /explain focus on bugs and improvements
    
    제공된 코드는 Kotlin으로 작성된 간단한 텍스트 모험 게임입니다. 사용자가 금색 LEGO砖을 찾거나
    방을 조사할 수 있게 해줍니다. 코드가 기능적이지만 몇 가지 잠재적인 버그 및 개선할 부분이 있습니다:
    
    1. 잠재적 버그:
    
    searchForBrick() 함수는 Math.random()을 사용하여 플레이어가 금색 LEGO砖을 찾는지 여부를 결정합니다. 그러나 이 함수는
    플레이어가 벽돌을 찾는 경우를 처리하지 않습니다. 게임은 플레이어가 벽돌을 찾은 후에도 무한정 계속됩니다.
    
    2. 개선 사항:
    
    게임 오버 조건: 플레이어가 금색 LEGO砖을 찾았을 때 적절한 게임 오버 조건이 있어야 합니다. 이는 불리언 플래그 또는 별도의 게임 상태를 도입하여 벽돌이 발견되었는지 추적함으로써 달성할 수 있습니다.
    
  3. /tests 명령을 사용하여 Duo Chat에게 선택된 코드에 대한 테스트를 생성해 달라고 요청합니다:

    /tests
    
    코드를 테스트하기 위해 Kotlin용 JUnit을 사용할 수 있습니다. 다음은 작성할 수 있는 테스트입니다:
    
      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("축하합니다! 금색 LEGO砖을 찾았습니다!"))
    
              System.setOut(standardOut)
          }
    
       ...
      }
    

모든 것이 테스트되었는지 확인한 후 선택한 코드를 리팩토링하도록 Duo Chat에게 요청합니다:

/refactor fix bugs, improve UX

...

개선 사항:

메뉴 인쇄 로직을 printMenu 함수로 분리하여 코드 조직 구조와 가독성을 개선했습니다.
Math.random() 대신 Random.nextDouble()을 사용하여 Kotlin의 표준 라이브러리와의 호환성을 향상시켰습니다.
메뉴를 인쇄한 후 사용자가 선택을 입력하라는 프롬프트를 추가했습니다.
createTextAdventure 함수에서 이미 값이 할당되므로 불필요한 gameOver 변수 초기화를 제거했습니다.
searchForBrick 함수에 추가 로직이나 게임 오버 조건을 추가하라는 주석을 추가했습니다.
이러한 변경은 코드의 가독성, 유지 보수성 및 사용자 경험을 개선할 것입니다.

리팩토링된 소스 코드는 다음과 같을 수 있습니다:

package org.example

import kotlin.random.Random

// 텍스트 모험 만들기
// 금색 LEGO砖 찾기
// 시각적 도우미 추가
// 게임 오버를 위한 랜덤 타이머 덫 사용
// 텍스트 모험 만들기
fun createTextAdventure() {
    println("금색 LEGO砖 모험에 오신 것을 환영합니다!")
    println("어두운 방에 놓인 자신을 발견했습니다. 무엇을 하시겠습니까?")

    var gameOver = false
    while (!gameOver) {
        printMenu()
        val choice = readLine()?.toIntOrNull()
        when (choice) {
            1 -> searchForBrick()
            2 -> examineRoom()
            3 -> {
                println("안녕히 가세요!")
                gameOver = true
            }
            else -> println("유효하지 않은 선택입니다. 다시 시도하세요.")
        }
    }
}

fun printMenu() {
    println("1. 금색 LEGO砖 찾기")
    println("2. 방 조사하기")
    println("3. 종료")
    print("선택을 입력하세요: ")
}

fun searchForBrick() {
    println("금색 LEGO砖의 흔적을 찾기 위해 방을 조심스럽게 수색합니다.")
    if (Random.nextDouble() < 0.2) {
        println("축하합니다! 금색 LEGO砖을 찾았습니다!")
        // 추가 로직 또는 게임 오버 조건 추가
    } else {
        println("검색 결과가 없습니다. 다시 시도해야 합니다.")
    }
}

fun examineRoom() {
    println("방을 둘러보며 세부 사항을 살펴봅니다.")
    println("방은 어둡고 모서리에 그림자가 있습니다.")
    println("북쪽에는 문이 있고 방 중앙에 테이블이 있습니다.")
}

fun main() {
    createTextAdventure()
}

PowerShell 시작하기

참고: PowerShell 지원은 실험적입니다.

  1. Duo Chat를 사용하여 현재 디렉터리의 파일 크기를 출력하는 PowerShell 스크립트를 시작하는 방법을 질문하세요.

    현재 디렉터리의 파일 크기를 출력하는 PowerShell 스크립트를 시작하는 방법은 무엇인가요?
    

    또는, Code Suggestions를 사용하여 소스 코드를 생성할 수 있습니다.

  2. 다음 내용을 사용하여 새로운 스크립트 get-file-sizes.ps1를 만드세요:

    # 디렉터리의 파일을 수집하고 그 크기를 출력합니다.
    
  3. Code Suggestions가 프롬프트를 완료할 때까지 기다린 후, 다음 프롬프트를 추가하여 다양한 출력 형식을 실험해 보세요:

    # 디렉터리의 파일을 수집하고 그 크기를 출력합니다.
    
    $directory = Read-Host -Prompt "파일 크기를 가져올 디렉터리 경로를 입력하세요"
    $files = Get-ChildItem -Path $directory -File
    foreach ($file in $files) {
        $fileSize = [Math]::Round(($file.Length / 1KB), 2)
        Write-Host "$($file.Name) - $fileSize KB"
    }
    
    # 위 코드를 반복하되 결과를 CSV 파일에 저장합니다.
    
  4. 다양한 내보내기 형식에 대한 프롬프트로 단계를 반복하거나 Code Suggestions 자동 완성을 사용하세요. 예를 들어:

# 디렉터리의 파일을 수집하고 그 크기를 출력합니다.

$directory = Read-Host -Prompt "파일 크기를 가져올 디렉터리 경로를 입력하세요"
$files = Get-ChildItem -Path $directory -File
foreach ($file in $files) {
    $fileSize = [Math]::Round(($file.Length / 1KB), 2)
    Write-Host "$($file.Name) - $fileSize KB"
}

# 위 코드를 반복하되 결과를 CSV 파일에 저장합니다.
$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 "파일 크기가 $csvFile에 저장되었습니다."

# 위 코드를 반복하되 결과를 JSON 파일에 저장합니다.
$jsonFile = "$directory\file-sizes.json"
$fileData | ConvertTo-Json | Out-File -FilePath $jsonFile
Write-Host "파일 크기가 $jsonFile에 저장되었습니다."

# 위 코드를 반복하되 결과를 XML 파일에 저장합니다.
$xmlFile = "$directory\file-sizes.xml"
$fileData | ConvertTo-Xml -NoTypeInformation | Out-File -FilePath $xmlFile
Write-Host "파일 크기가 $xmlFile에 저장되었습니다."

# 위 코드를 반복하되 결과를 HTML 파일에 저장합니다.
$htmlFile = "$directory\file-sizes.html"
$fileData | ConvertTo-Html -Property FileName, FileSize | Out-File -FilePath $htmlFile
Write-Host "파일 크기가 $htmlFile에 저장되었습니다."

# 위 코드를 반복하되 결과를 TXT 파일에 저장합니다.
$txtFile = "$directory\file-sizes.txt"
$fileData | Out-File -FilePath $txtFile
Write-Host "파일 크기가 $txtFile에 저장되었습니다."

취약점 설명 및 해결

C 코드의 취약점

이 예에서는 C에서 감지된 보안 취약점을 GitLab Duo의 도움으로 수정해야 합니다.

이 단계의 과정을 시청하세요 GitLab Duo Coffee Chat: Vulnerability Resolution Challenge #1

이 소스 코드 스니펫버퍼 오버플로가 있는 보안 취약점을 도입합니다:

    strcpy(region, "Hello GitLab Duo Vulnerability Resolution challenge");

    printf("지역의 내용: %s\n", region);

SAST 보안 스캐너는 문제를 감지하고 보고할 수 있습니다. 취약점 설명을 사용하여 문제를 이해하세요.

취약점 해결은 MR을 생성하는 데 도움이 됩니다.

제안된 변경 사항이 요구 사항에 맞지 않거나 문제를 일으킬 수 있는 경우 Code Suggestions 및 Duo Chat을 사용하여 개선할 수 있습니다. 예를 들어:

  1. GitLab Duo가 활성화된 VS Code 또는 웹 IDE를 열고 지침이 포함된 주석을 추가하세요:

        // 잠재적인 버퍼 오버플로를 피하세요.
    
        // 아래는 AI가 생성한 코드입니다.
        strncpy(region, "Hello GitLab Duo Vulnerability Resolution challenge", pagesize);
        region[pagesize-1] = '\0';
        printf("지역의 내용: %s\n", region);
    
  2. 제안된 코드를 삭제하고 대체 방법을 사용하라는 다른 주석을 사용하세요.

        // snprintf()를 사용하여 잠재적인 버퍼 오버플로를 피하세요.
    
        // 아래는 AI가 생성한 코드입니다.
        snprintf(region, pagesize, "Hello GitLab Duo Vulnerability Resolution challenge");
    
        printf("지역의 내용: %s\n", region);
    
  3. GitLab Duo Chat을 사용하여 질문하세요. /refactor 코드 작업은 다양한 제안을 생성할 수 있습니다.

    특정 알고리즘이나 함수를 선호하는 경우 프롬프트를 수정할 수 있습니다:

    /refactor using snprintf
    

리소스:

GitLab에 대한 질문에 답하기

이 예제에서 도전 과제는 GitLab Duo Chat을 사용하여 문제를 해결하는 것입니다.

GitLab Duo Coffee Chat: GitLab Duo Chat Challenge로 문제 해결하기에서 이러한 단계에 대한 설명을 시청하세요.

  • GitLab Duo Chat을 사용하여 CI/CD 오류를 설명할 수 있습니다.

    이 CI/CD 오류를 설명하세요: build.sh: line 14: go command not found
    
  • 조급해하지 말고 하나 또는 두 단어만 입력하면 어떻게 됩니까?

    labels
    
    issue labels
    

    GitLab Duo Chat은 추가 맥락을 요청합니다.

  • 문제를 설명하고 해결책을 요청하는 풀 문장으로 질문을 다듬으세요.

    GitLab에서 레이블을 설명하세요. 효율적인 사용을 위한 예를 제공하세요.
    

리소스:

근본 원인 분석 사용 사례

근본 원인 분석을 사용하여 CI/CD 파이프라인 실패의 근본 원인을 파악하세요. 다음 예제는 일반적인 오류를 설명하고, 포크하여 근본 원인을 찾고 수정하는 연습을 장려합니다.

자세한 내용은 블로그 게시물 GitLab Duo 개발: AI와 근본 원인 분석을 결합하여 CI/CD 파이프라인 수정하기를 참고하세요.

누락된 Go 런타임 분석

CI/CD 작업은 기여된 image 속성에서 생성된 컨테이너 내에서 실행될 수 있습니다. 컨테이너가 프로그래밍 언어 런타임을 제공하지 않는 경우, go 바이너리를 참조하는 실행된 script 섹션이 실패합니다. 예를 들어, 오류 메시지 /bin/sh: eval: line 149: go: not found를 이해하고 수정해야 합니다. 컨테이너의 런타임 컨텍스트에서 go 명령이 발견되지 않는 이유는 여러 가지가 있을 수 있습니다:

  • 작업이 alpine과 같은 최소 컨테이너 이미지를 사용하고 있으며 Go 언어 런타임이 설치되지 않았습니다.
  • 작업이 CI/CD 구성에서 지정된 잘못된 기본 컨테이너 이미지를 사용하거나 default 키워드를 사용합니다.
  • 작업이 컨테이너 이미지 대신 셸 실행기를 사용합니다. 호스트 운영 체제가 손상되었거나 Go 언어 런타임이 설치되어 있지 않거나 구성되지 않았습니다.

프로젝트 도전 과제: 근본 원인 분석 - Go GitLab 릴리스 페처는 Go Tanuki 애플리케이션으로 CI/CD 문제를 분석하고 수정하는 연습을 제공합니다. 이 연습에서 builddocker-build 작업이 실패하고 있습니다. 문제를 수정하면 CI/CD 파이프라인이 성공하고 build 작업이 출력을 인쇄합니다. solution/ 디렉토리는 근본 원인 분석 후 두 가지 가능한 솔루션을 제공합니다.

GitLab에 기여하기 위해 GitLab Duo 사용하기

GitLab Duo 사용은 GitLab 코드베이스에 기여하는 데 중점을 두며, 고객이 더 효율적으로 기여할 수 있는 방법을 설명합니다.

GitLab 코드베이스는 방대하며, 때로는 복잡한 알고리즘이나 애플리케이션 특정 구현을 이해해야 합니다.

자세한 내용을 보려면 아키텍처 구성 요소를 검토하세요.

프론트엔드 기여: 프로필 설정

이 예제에서 문제는 GitLab 프로필 페이지를 업데이트하고 소셜 네트워크 설정을 개선하는 것입니다.


여기서 녹화를 시청하세요: GitLab Duo Coffee Chat: GitLab에 코드 제안 및 채팅을 사용하여 기여하기

GitLab Duo Chat를 사용하여 코드를 설명하고 리팩토링하며 테스트를 생성할 수 있습니다.
코드 제안은 기존 코드를 완성하는 데 도움을 주며, Ruby, Go 또는 VueJS에서 새로운 함수와 알고리즘을 생성할 수 있습니다.

  1. 선택한 코드 섹션을 설명하기 위해 /explain 코드 작업을 사용하고, HAML 템플릿이 어떻게 작동하는지 배웁니다.

  2. 코드 작업 프롬프트를 수정하여 /explain how HAML rendering works를 대신 요청할 수 있습니다.

대안으로, 다음과 같이 채팅 프롬프트에 직접 작성할 수 있습니다:

how to populate a select in haml

리팩토링 예제는 다음을 포함합니다:

  1. /refactor into a HAML dropdown
  2. 기존 UI 양식 코드를 검사한 후, 프롬프트를 /refactor into a HAML dropdown with a form select로 수정합니다.

GitLab Duo Chat은 오류 디버깅에 도움을 주었으며, 오류 메시지를 접두어로 추가했습니다:

please explain this error: undefined method `icon` for

코드 생성 프롬프트

다음 예제는 GitLab Duo의 지원되는 언어에 대한 코드 생성 프롬프트를 제공합니다.
코드 생성 프롬프트를 수정하기 위해 여러 줄 주석을 사용할 수 있습니다.

예제는 GitLab Duo Prompts 프로젝트에서 저장되어 있으며,
개발자 관계 팀에서 유지 관리합니다. 이 예제는 작동을 테스트한 것입니다. 귀하의 환경에 맞게 검토하고 조정해야 합니다.

C 코드 생성 프롬프트

I/O, 성능, 디스크 사용량 및 TCP 지연 시간을 수집하고 이를 출력하는 Linux 통계 도구를 만듭니다.
전체 예제는 블로그 게시물 GitLab Duo 블로그 게시물에서 AI 기반 코드 제안의 효율적인 팁을 참조하십시오.

// 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++ 코드 생성 프롬프트

CLI 애플리케이션을 생성하여 HTTP 클라이언트 역할을 합니다.

// HTTP 클라이언트로서 CLI 애플리케이션 생성
// 메인 함수 생성
// 모든 헤더 포함
// 프로그램 옵션 읽기: URL, API 엔드포인트, 기본 인증

#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;

  // 명령줄 옵션 파싱
  // ...

  CURL* curl = curl_easy_init();
  if(curl) {
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());

    // 기본 인증 설정
    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 << "요청 실패: " << curl_easy_strerror(res) << std::endl;
    }

    curl_easy_cleanup(curl);
  }

  return 0;
}

분산 파일 노드를 관리하는 애플리케이션을 생성합니다.

// 분산 파일 노드를 관리하는 애플리케이션 생성
// 노드의 상태 개요 제공
// 기본 파일 노드를 정의하기 위해 OOP 패턴 사용
// 기본 파일에서 상속된 특정 파일 시스템 추가

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 프로그램을 생성합니다.

리눅스 커널에서만 작동합니다.

// XDP 커널 이벤트에 연결되는 eBPF 프로그램 생성
// IP 주소별 모든 패킷 수 세기
// 요약 출력
// 필요한 헤더 포함

#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 생성 소스 코드 예제는 c++ 디렉토리에서 GitLab Duo Prompts 프로젝트에서 확인할 수 있습니다.

C# 코드 생성 프롬프트

다양한 센서에서 데이터를 수집하고 MSSQL에 저장하는 의료 분석기 앱을 만듭니다.

// 의료 분석기 앱 생성
// 다양한 센서에서 데이터 수집
// MSSQL에 데이터 저장
// 센서 데이터에 접근하는 메서드 제공

using System.Data.SqlClient;

namespace MedicalAnalyzer
{
    public class SensorDataStore
    {
        private SqlConnection connection;

        public SensorDataStore()
        {
            // SQL Server 연결 생성
            connection = new SqlConnection("connection string here");
        }

        public void StoreSensorData(SensorData data)
        {
            // 연결 열기
            connection.Open();

            // 데이터베이스에 센서 데이터 삽입
            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();

            // 연결 닫기
            connection.Close();
        }

        public SensorData[] GetSensorData(DateTime startTime, DateTime endTime)
        {
            // 데이터베이스 쿼리 및 결과 반환
        }
    }
}

AI가 생성한 소스 코드 예제는 c# 디렉토리에서 GitLab Duo Prompts 프로젝트에서 확인할 수 있습니다.

CSS 코드 생성 프롬프트

/* 무지개 애니메이션을 위한 CSS 클래스 생성 */

@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가 생성한 소스 코드 예제는 css 디렉토리에서 GitLab Duo Prompts 프로젝트에서 확인할 수 있습니다.

Go 코드 생성 프롬프트

Kubernetes를 위한 가시화 애플리케이션을 만들어 클러스터의 컨테이너, 포드 및 서비스 상태를 읽고 인쇄합니다.

// Kubernetes 가시성을 위한 클라이언트 생성
// 함수를 생성하여
// KUBECONFIG 환경 변수에서 Kubernetes 구성 파일 읽기
// Kubernetes 컨텍스트 생성, 네임스페이스 기본값
// 컨테이너, 포드, 서비스 상태 검사 및 개요 인쇄
// 필요한 패키지 가져오기
// 메인 패키지 생성

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)

}

// 컨테이너를 인쇄하는 함수 생성
// 수집 및 카운트 인쇄

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에서 확인하세요.

// Redis와 유사한 메모리 내 키 값 저장소 생성
// 다음에 대한 메서드 제공
// 키 설정/해제
// 값 업데이트
// 필터와 함께 목록/인쇄
// 외부 라이브러리로 BoltDB 사용

AI가 생성한 소스 코드 예제는 go 디렉토리에서 GitLab Duo Prompts 프로젝트에서 확인할 수 있습니다.

Java 코드 생성 프롬프트

데이터에 대한 다양한 출처를 가진 데이터 분석 애플리케이션을 만듭니다.

메트릭에 대한 API를 제공합니다.

// 데이터 분석 앱 생성
// 다양한 입력 소스와 해당 값을 파싱
// 메트릭을 열 형식으로 저장
// 데이터 조회 및 집계를 위한 API 제공

AI가 생성한 소스 코드 예제는 GitLab Duo Prompts 프로젝트의 java 디렉토리에서 확인할 수 있습니다.

JavaScript 코드 생성 프롬프트

ReactJS에서 직원들을 위한 유급 휴가 애플리케이션을 만듭니다.

날짜-시간 선택기를 추가합니다.

// 사용자용 유급 휴가 앱 생성
// ReactJS에서 날짜-시간 선택기 생성
// 시작 및 종료 옵션 제공
// 선택한 국가에 따라 공휴일 표시
// 요청을 서버 API에 전송

AI가 생성한 소스 코드 예제는 GitLab Duo Prompts 프로젝트의 javascript 디렉토리에서 확인할 수 있습니다.

HTML 코드 생성 프롬프트

<!-- AI 지식 기반을 생성합니다.
AI가 효율적인 DevSecOps 워크플로우에 어떻게 도움이 되는지 설명합니다.
하나의 Dev, 하나의 Ops, 하나의 Sec 예제를 포함한 표를 추가합니다.
-->

<table>
  <tr>
    <th>Dev</th>
    <th>Ops</th>
    <th>Sec</th>
  </tr>
  <tr>
    <td>자동화된 테스트 및 지속적 통합</td>
    <td>코드로서의 인프라 및 자동화된 프로비저닝</td>
    <td>정적 코드 분석 및 취약점 스캐닝</td>
  </tr>
</table>

AI가 생성한 소스 코드 예제는 GitLab Duo Prompts 프로젝트의 html 디렉토리에서 확인할 수 있습니다.

Kotlin 코드 생성 프롬프트

텍스트 어드벤처를 생성하고 보물을 찾습니다.

시각적 도우미를 추가하고 게임 오버를 위한 무작위 타이머 함정을 사용합니다.

package org.example

// 텍스트 어드벤처 생성
// 금색 LEGO 블록을 찾기
// 시각적 도우미 추가
// 게임 오버를 위한 무작위 타이머 함정 사용
// 텍스트 어드벤처 생성
fun createTextAdventure() {
    println("금색 LEGO 블록 모험에 오신 것을 환영합니다!")
    println("어두운 방에 있다고 가정해 보세요. 무엇을 하시겠습니까?")

    var gameOver = false
    while (!gameOver) {
        println("1. 금색 LEGO 블록을 검색")
        println("2. 방을 검사")
        println("3. 종료")

        val choice = readLine()?.toIntOrNull() ?: 0
        when (choice) {
            1 -> searchForBrick()
            2 -> examineRoom()
            3 -> {
                println("안녕히 가세요!")
                gameOver = true
            }
            else -> println("잘못된 선택입니다. 다시 시도하세요.")
        }
    }
}

fun searchForBrick() {
    println("금색 LEGO 블록의 흔적을 찾으며 방을 조심스럽게 검색합니다.")
    if (Math.random() < 0.2) {
        println("축하합니다! 금색 LEGO 블록을 찾았습니다!")
    } else {
        println("검색해도 아무것도 나오지 않았습니다. 다시 시도해야 합니다.")
    }
}

fun examineRoom() {
    println("방을 둘러보며 세부 사항을 살펴봅니다.")
    println("방은 어두운 조명으로 밝혀져 있고, 구석에 그림자가 있습니다.")
    println("북쪽에는 문이 있고, 방 중앙에 탁자가 있습니다.")
}

fun main() {
    createTextAdventure()
}

AI가 생성한 소스 코드 예제는 GitLab Duo Prompts 프로젝트의 kotlin 디렉토리에서 확인할 수 있습니다.

PHP 코드 생성 프롬프트

GitLab 릴리스를 위한 RSS 피드 가져오기 생성, 제목으로 필터링 허용.

// GitLab 릴리스를 표시하는 웹 양식 생성
// https://about.gitlab.com/atom.xml에서 RSS 피드 가져오기
// 제목에 대한 필터 옵션 제공하기

$feedUrl = 'https://about.gitlab.com/atom.xml';

$xml = simplexml_load_file($feedUrl);

$titleFilter = $_GET['titleFilter'];

echo '<h1>GitLab 릴리스</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가 생성한 소스 코드 예제는 php 디렉토리에서 확인할 수 있습니다.

PowerShell 코드 생성 프롬프트

디렉토리의 모든 파일을 수집하고 파일 크기를 인쇄하는 스크립트 생성.

결과를 CSV 또는 JSON 파일에 저장하도록 프롬프트 수정.

# 디렉토리의 파일을 수집하고 크기를 인쇄하기

$directory = Read-Host -Prompt "파일 크기를 얻기 위한 디렉토리 경로 입력"
$files = Get-ChildItem -Path $directory -File
foreach ($file in $files) {
    $fileSize = [Math]::Round(($file.Length / 1KB), 2)
    Write-Host "$($file.Name) - $fileSize KB"
}

# 위의 코드를 반복하지만 결과를 CSV 파일에 저장

$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 "파일 크기가 $csvFile에 저장되었습니다."

# 위의 코드를 반복하지만 결과를 JSON 파일에 저장

$jsonFile = "$directory\file-sizes.json"
$fileData | ConvertTo-Json | Out-File -FilePath $jsonFile
Write-Host "파일 크기가 $jsonFile에 저장되었습니다."

AI가 생성한 소스 코드 예제는 powershell 디렉토리에서 확인할 수 있습니다.

Python 코드 생성 프롬프트

REST API를 사용하여 사용자 관리용 Flask 웹 서버 생성, SQLite에 사용자 저장.

# Flask 웹서버 생성
# ID로 사용자를 관리하는 REST API 엔드포인트 추가
# 생성, 업데이트, 삭제 기능 구현
# 사용자 데이터는 SQlite에 저장되며, 존재하지 않을 경우 테이블 생성
# 서버를 8080 포트에서 실행하고, TLS 지원
# requirements.txt에 필요한 패키지를 주석으로 출력.
# 기본 Python 3.10 사용

# AI가 생성한 코드 가능성 아래
import flask
from flask import request
import sqlite3

app = flask.Flask(__name__)

# 존재하지 않을 경우 SQLite 데이터베이스 및 사용자 테이블 생성
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():
  # 요청에서 사용자 데이터 가져오기
  name = request.form['name']
  email = request.form['email']

  # 데이터베이스에 사용자 삽입
  conn.execute('INSERT INTO users (name, email) VALUES (?, ?)', (name, email))

  return '사용자가 성공적으로 생성되었습니다.'

@app.route('/users/<int:id>', methods=['PUT'])
def update_user(id):
  # 요청에서 사용자 데이터 가져오기
  name = request.form['name']
  email = request.form['email']

  # 데이터베이스에서 사용자 업데이트
  conn.execute('UPDATE users SET name = ?, email = ? WHERE id = ?', (name, email, id))

  return '사용자가 성공적으로 업데이트되었습니다.'

@app.route('/users/<int:id>', methods=['DELETE'])
def delete_user(id):
  # 데이터베이스에서 사용자 삭제
  conn.execute('DELETE FROM users WHERE id = ?', (id,))

  return '사용자가 성공적으로 삭제되었습니다.'

if __name__ == '__main__':
  # 필요한 패키지 - flask, sqlite3
  app.run(host='0.0.0.0', port=8080, ssl_context='adhoc')

AI가 생성한 소스 코드 예제는 python 디렉토리에서 확인할 수 있습니다.

루비 코드 생성 프롬프트

로그 데이터를 Elasticsearch에 저장하는 로그 파서 애플리케이션을 생성하세요.

# 로그 파서로서 Ruby 앱 생성
# 로그 라인의 민감한 문자열을 대체할 수 있는 후크 제공
# 로그를 형식화하고 Elasticsearch에 저장

# 잠재적인 AI 생성 코드 아래
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)
    # 민감한 데이터 교체
    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 형식과 심각도 수준, 애플리케이션 이름 및 메시지 문자열을 지원하는 로그 클라이언트 유틸리티 클래스를 생성하세요.

# 로깅 유틸리티 클래스 생성
# 기본 로그 레벨을 속성으로 정의
# 로깅 메서드 추가, 입력: 레벨, 앱, 메시지
# syslog 형식으로 날짜 및 시간 형식이 지정된 데이터 출력

# 잠재적인 AI 생성 코드 아래
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

# 클래스를 인스턴스화하고 로그 메서드를 테스트하세요.

# 잠재적인 AI 생성 코드 아래
logger = Logging.new
logger.log_level = :debug

logger.log(:info, 'MyApp', '애플리케이션 시작 - 정보')
logger.log(:debug, 'MyApp', '애플리케이션 시작 - 디버그')
logger.log(:error, 'MyApp', '애플리케이션 시작 - 오류')
logger.log(:fatal, 'MyApp', '애플리케이션 시작 - 치명적')
logger.log(:warn, 'MyApp', '애플리케이션 시작 - 경고')

AI가 생성한 소스 코드 예제는 GitLab Duo Prompts 프로젝트의 ruby 디렉토리에서 확인할 수 있습니다.

러스트 코드 생성 프롬프트

// GitLab REST API 쿼리
// 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: 페이지 매김, 기본 가져오기 결과: 20
    // 응답 헤더를 읽어 다음 페이지에 접근

    println!("{}", json.to_string());

    for mr in json.as_array().unwrap() {
        println!("{} - URL: {}", mr["title"], mr["web_url"]);
    }
}

RSS 피드 리더 애플리케이션을 생성하세요. 예제는 AI의 도움으로 고급 Rust 프로그래밍을 배우기 블로그 게시물에 있습니다.

    // 소스 배열을 반복하고
    // RSS 피드 항목에서 데이터를 HTTP를 사용하여 가져오는 함수를 생성하세요.
    // 결과를 새 해시맵에 저장하세요.
    // 해시맵을 터미널에 출력하세요.

AI가 생성한 소스 코드 예제는 GitLab Duo Prompts 프로젝트의 rust 디렉토리에서 확인할 수 있습니다.

Scala 코드 생성 프롬프트

// 뉴턴 방법 구현하기
// 메인 함수를 가진 객체 생성하기
// 방정식을 해결하기 위해 뉴턴 방법을 구현하는 함수 추가하기
// 구현된 함수를 테스트하는 드라이버 함수 추가하기
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"루트는: $root")
  }
}

AI 생성 소스 코드 예제는 scala 디렉토리에서 GitLab Duo Prompts 프로젝트에서 확인할 수 있습니다.

셸 스크립트 코드 생성 프롬프트

mytop.sh라는 스크립트를 작성하여 CPU, 메모리 및 디스크 I/O 사용량에 따라 상위 10개 프로세스를 표시합니다.

코드 주석으로 시작하여 코드 제안이 나머지를 생성하도록 합니다.

#!/bin/bash

# CPU 사용량 기준 상위 10개 프로세스 가져오기
top -b -n 1 | head -n 11 | awk '{print $1, $2, $3, $9}' | column -t

# 메모리 사용량 기준 상위 10개 프로세스 가져오기
top -b -n 1 | head -n 11 | awk '{print $1, $2, $4, $6}' | column -t

# 디스크 I/O 기준 상위 10개 프로세스 가져오기
top -b -n 1 | head -n 11 | awk '{print $1, $2, $7, $8}' | column -t

# 네트워크 I/O 기준 상위 10개 프로세스 가져오기
top -b -n 1 | head -n 11 | awk '{print $1, $2, $10, $11}' | column -t

AI 생성 소스 코드 예제는 shell 디렉토리에서 GitLab Duo Prompts 프로젝트에서 확인할 수 있습니다.

TypeScript 코드 생성 프롬프트

IPv6 및 IPv4 주소 형식을 구문 분석하는 유틸리티 함수를 만듭니다.

"use strict";
// IPv6 및 IPv4 주소 형식을 구문 분석하는 TypeScript 함수를 생성합니다.
// 정규 표현식 사용
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('잘못된 IP 주소');
    }
}
// 임의의 입력으로 함수 테스트하기
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(`잘못된 주소: ${input}`);
    }
}

AI 생성 소스 코드 예제는 typescript 디렉토리에서 GitLab Duo Prompts 프로젝트에서 확인할 수 있습니다.

리소스

많은 사용 사례는 GitLab Duo Coffee Chat YouTube 재생목록에서 실습 녹화로 제공됩니다.

GitLab Duo Coffee ChatDeveloper Relations 팀이 관리하는 학습 시리즈입니다.

블로그 리소스

다음 블로그 게시물은 이러한 사용 사례에 대한 튜토리얼을 제공합니다:

코드 제안 튜토리얼 블로그 게시물은 다음 언어에 대해 제공됩니다: