This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Contributing

Guidelines for contributing to Divekit.

Learn how to contribute to the Divekit project.

1 - Development Setup

How to set up your development environment for contributing to Divekit.

This guide will help you set up your development environment for contributing to Divekit.

Prerequisites

  • Command Line access
  • Internet connection
  • Go 1.23 or higher
  • Gitlab
    • Access Token
    • Group IDs
  • (Git)
  • (npm)

Setting Up the Development Environment

  1. Clone the repository:
git clone https://gitlab.git.nrw/divekit/tools/divekit-cli.git
  1. Navigate to the project directory:
cd divekit-cli
  1. Install the required dependencies:
go mod download

Install local modules (later possibly optional - but for development a huge help):

mkdir pkg
cd pkg
git clone https://gitlab.git.nrw/divekit/modules/gitlab-adapter
git clone https://gitlab.git.nrw/divekit/modules/config-management

cd ..
go work init
go work use ./pkg/gitlab-adapter
go work use ./pkg/config-management
  1. Build the CLI:

Build the CLI

chmod +x build.sh
./build.sh

Then answer the questions or just press Enter for the default values (windows, amd64).

This will create a divekit executable in the bin directory. You can run this executable from the command line to use the CLI or run install on it to install it globally.

For Example:

./bin/divekit_windows_amd64.exe install

This will install the divekit command globally on your system. You can now run divekit from any directory.

  1. Run the CLI:
./bin/divekit_windows_amd64.exe

# or

divekit

…or if you want to execute directly from the source code:

go run cmd/divekit/main.go
  1. Run the tests:
go test ./...
  1. Make your changes and submit a merge request.

2 - Error Handling

Guidelines and patterns for error handling in Divekit.

The project implements a structured error handling system that distinguishes between critical and non-critical errors. This pattern is currently implemented in the distribute package and can serve as a template for other packages.

Error Pattern

Each package can define its own error types and handling behavior. The pattern consists of:

  1. A custom error type that implements the error interface
  2. Specific error types as constants
  3. Methods to determine error severity and behavior

Example from the distribute package:

// Custom error type
type CustomError struct {
    ErrorType ErrorType
    Message   string
    Err       error
}

// Error types
const (
    // Critical errors that lead to termination
    ErrConfigLoad       // Configuration loading errors
    ErrWorkingDir      // Working directory access errors
    
    // Non-critical errors that trigger warnings
    ErrMembersNotFound // Member lookup failures
)

Example Implementation

Here’s how to implement this pattern in your package:

// Create a new error
if err := loadConfig(); err != nil {
    return NewCustomError(ErrConfigLoad, "failed to load configuration", err)
}

// Handle non-critical errors
if err := validateData(); err != nil {
    if !err.IsCritical() {
        log.Warn(err.Error())
        // Continue execution...
    } else {
        return err
    }
}

Error Behavior

Each package can define its own error behavior, but should follow these general principles:

  • Critical Errors: Should terminate the current operation
  • Non-Critical Errors: Should generate warnings but allow continuation
  • Wrapped Errors: Should preserve the original error context

Each error should include:

  • An error type indicating its severity
  • A descriptive message
  • The original error (if applicable)
  • A method to determine if it’s critical

This pattern provides consistent error handling while remaining flexible enough to accommodate different package requirements. The distribute package provides a reference implementation of this pattern.

3 - Contributing Guidelines

Guidelines and best practices for contributing to the Divekit project.

Thank you for considering contributing to Divekit! This document outlines our contribution process and guidelines.

Code of Conduct

  • Be respectful and inclusive
  • Follow professional standards
  • Help others learn and grow
  • Report unacceptable behavior

Getting Started

  1. Fork the repository
  2. Set up your development environment
  3. Create a feature branch
  4. Make your changes
  5. Submit a pull request

Development Process

Branching Strategy

  • main: Production-ready code
  • develop: Integration branch
  • Feature branches: feature/your-feature
  • Bugfix branches: fix/issue-description

Commit Messages

Follow conventional commits:

type(scope): description

[optional body]

[optional footer]

The commit message header consists of three parts:

  • type: Categorizes the type of change (see below)
  • scope: Indicates the section of the codebase being changed (e.g. cli, core, config, parser)
  • description: Brief description of the change in imperative mood

Examples:

  • feat(cli): add new flag for verbose output
  • fix(parser): handle empty config files correctly
  • docs(readme): update installation instructions
  • test(core): add tests for user authentication

Types:

  • feat: New feature or functionality
  • fix: Bug fix
  • docs: Documentation changes
  • style: Formatting, missing semicolons, etc. (no code changes)
  • refactor: Code restructuring without changing functionality
  • test: Adding or modifying tests
  • chore: Maintenance tasks, dependencies, etc.

The body should explain the “why” of the change, while the description explains the “what”.

Pull Requests

  1. Update documentation
  2. Add/update tests
  3. Ensure CI passes
  4. Request review
  5. Address feedback

Code Style

  • Follow Go best practices and idioms
  • Use gofmt for consistent formatting
  • Follow the official Go Code Review Comments
  • Use golint and golangci-lint
  • Write clear, idiomatic Go code
  • Keep functions focused and well-documented

Testing

  • Write unit tests using the standard testing package
  • Use table-driven tests where appropriate
  • Aim for good test coverage
  • Write integration tests for complex functionality
  • Use go test for running tests
  • Consider using testify for assertions

Documentation

  • Write clear godoc comments
  • Update README.md and other documentation
  • Include examples in documentation
  • Document exported functions and types
  • Keep documentation up to date with changes

Review Process

  1. Automated checks (golangci-lint, tests)
  2. Code review
  3. Documentation review
  4. Final approval
  5. Merge

Release Process

  1. Version bump
  2. Changelog update
  3. Tag release
  4. Documentation update