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

Return to the regular view of this page.

Quick Start

Learn what Divekit is and how it can help you manage programming assignments.

Divekit is a command-line tool for managing individualized programming assignments at scale. It helps educators create, distribute and evaluate programming exercises for large groups of students.

Key Features

  • Assignment Individualization: Generate unique variations of programming assignments for each student
  • Automated Distribution: Create and manage GitLab repositories for students automatically
  • Test Integration: Built-in support for automated testing and evaluation
  • Bulk Operations: Efficiently manage assignments for large classes
  • Access Control: Manage repository access rights and permissions

Benefits

  • Prevent Plagiarism: Each student receives a slightly different version of the assignment
  • Save Time: Automate repetitive tasks like repository setup and access management
  • Ensure Fairness: Standardized testing and evaluation across all variations
  • Scale Easily: Handle large classes with minimal additional effort

Use Cases

Divekit is primarily used in educational settings where:

  • Programming assignments need to be distributed to many students
  • Each student should receive an individualized version
  • Automated testing and evaluation is desired
  • Manual administrative overhead should be minimized

The tool consolidates functionality that was previously spread across multiple separate tools into a single, easy-to-use CLI application.

Divekit is a toolkit for managing individualized programming assignments at scale.

1 - Hello there πŸ‘‹

Learn what Divekit is and how it can help you manage programming assignments.

What is Divekit?

Divekit is a command-line tool for managing individualized programming assignments at scale. It helps educators create, distribute and evaluate programming exercises for large groups of students.

Visual overview: from origin to distributed repositories

Locally:

my-assignment/
β”œβ”€ .divekit/
β”œβ”€ src/$Vehicle$.java            # placeholder - used by individualization
β”œβ”€ test_sandbox/                 # filter - excluded from student repos
└─ README.md

Gitlab: “Individualized repositories”:

gitlab.example.com/.../my-group/    # Code repositories (main target)
β”œβ”€ my-assignment-4d2c0752-f400-4690-9bac-97c927e68e17/
β”‚  β”œβ”€ src/Car.java                  # $Vehicle$ β†’ Car
β”‚  └─ README.md
β”œβ”€ my-assignment-4d243142-292b-4b95-abbb-af13f102c857/
β”‚  β”œβ”€ src/Bike.java                 # $Vehicle$ β†’ Bike
β”‚  └─ README.md
└─ my-assignment-8153ded6-ee91-4135-b59e-ace2625f83c3/
   β”œβ”€ src/Plane.java                # $Vehicle$ β†’ Plane
   └─ README.md

Gitlab: “Secure pipeline” (students cannot access)

gitlab.example.com/.../my-sandbox/
β”œβ”€ my-assignment-4d2c0752-f400-4690-9bac-97c927e68e17/
β”‚  β”œβ”€ src/Car.java                  # $Vehicle$ β†’ Car
β”‚  β”œβ”€ test/                 
β”‚  └─ README.md
β”œβ”€ my-assignment-4d243142-292b-4b95-abbb-af13f102c857/
β”‚  β”œβ”€ src/Bike.java                 # $Vehicle$ β†’ Bike
β”‚  β”œβ”€ test/                 
β”‚  └─ README.md
└─ my-assignment-8153ded6-ee91-4135-b59e-ace2625f83c3/
   β”œβ”€ src/Plane.java                # $Vehicle$ β†’ Plane
   β”œβ”€ test/                 
   └─ README.md

Key Features

  • Assignment Individualization: Generate unique variations of programming assignments for each student
  • Automated Distribution: Create and manage GitLab repositories for students automatically
  • Test Integration: Built-in support for automated testing and evaluation
  • Bulk Operations: Efficiently manage assignments for large classes
  • Access Control: Manage repository access rights and permissions

Benefits

  • Prevent Plagiarism: Each student receives a slightly different version of the assignment
  • Save Time: Automate repetitive tasks like repository setup and access management
  • Ensure Fairness: Standardized testing and evaluation across all variations
  • Scale Easily: Handle large classes with minimal additional effort

Use Cases

Divekit is primarily used in educational settings where:

  • Programming assignments need to be distributed to many students
  • Each student should receive an individualized version
  • Automated testing and evaluation is desired
  • Manual administrative overhead should be minimized

The tool consolidates functionality that was previously spread across multiple separate tools into a single, easy-to-use CLI application.

Divekit is a toolkit for managing individualized programming assignments at scale.

Who needs Divekit?

Divekit is designed for different stakeholders in programming education:

Course Instructors

Primary users who:

  • Create and manage programming assignments
  • Need to distribute exercises to large groups of students
  • Want to prevent plagiarism through individualization
  • Need efficient ways to evaluate student submissions

Benefits

  • Automated repository management
  • Built-in individualization system
  • Integrated testing capabilities
  • Bulk operations for large classes

Teaching Assistants

Support staff who:

  • Help manage student repositories
  • Assist with assignment evaluation
  • Provide technical support to students

Benefits

  • Standardized repository structure
  • Automated access management
  • Consistent testing environment
  • Clear overview of student progress

Students

End users who:

  • Receive individualized assignments
  • Submit their solutions through Git
  • Get automated feedback on their work

Benefits

  • Personal GitLab repositories
  • Immediate feedback through automated tests
  • Clear assignment structure
  • Consistent submission process

2 - Installation

Step-by-step guide to installing the Divekit CLI and required dependencies.

Prerequisites

Before installing Divekit, ensure your system meets the following requirements:

System Requirements

  • Operating System: Linux, macOS, or Windows
  • GitLab: Access to a GitLab instance with API permissions

GitLab Setup

  1. Access to a GitLab instance
  2. Admin rights to create groups and repositories
  3. Personal Access Token with api scope

Creating a Personal Access Token

  1. Create one here

or

  1. Navigate to your GitLab profile settings
  2. Go to “Access Tokens”
  3. Create a new token with required scopes
  4. Save the token securely - you’ll need it during installation

Storage Requirements

  • Minimum 1GB free disk space
  • Additional space for repositories (varies by project size)

Network Requirements

  • Stable internet connection
  • Access to GitLab API endpoints
  • No blocking firewalls for HTTP requests

Optional Requirements

  • Docker: For running tests in containers
  • Maven/Gradle: For Java project support
  • IDE: Any Git-compatible IDE for development
  • Java: Version 11 or higher (only required for UMLet diagram processing)

Installation

  1. Download the latest release:

  2. Install Divekit:
    Navigate to the download directory and run the installation script:

./divekit.exe install  # On Windows
./divekit install      # On Linux/macOS

Environment Setup

After installation, configure your GitLab hosts and tokens using the divekit config command. Tokens are stored securely in your operating system’s credential store (macOS Keychain, Windows Credential Manager, Linux Secret Service).

The DIVEKIT_MEMBERS environment variable is optional for the path for your members files.

GitLab Host and Token Configuration

Use divekit config set @hosts to add your GitLab instance(s). This records the host configuration in ~/.divekit/hosts.json and stores the token in the OS credential manager.

Steps
  1. Create a Personal Access Token (if not already done):

    • Go to your GitLab profile > Access Tokens.
    • Create a token with api scope.
    • Copy the token.
  2. Add the Host:

    # Simplified syntax with automatic token prompt
    divekit config set @hosts git-nrw https://gitlab.git.nrw/
    
    # Or with direct token (for non-interactive use)
    divekit config set @hosts git-nrw https://gitlab.git.nrw/ --token glpat-xxx...
    
    # Traditional syntax
    divekit config set @hosts.git-nrw.host https://gitlab.git.nrw/
    divekit config set @hosts.git-nrw.token glpat-xxx...
    

    The token is prompted if not provided and stored in the OS credential manager.

  3. Verify:

    divekit config get @hosts.git-nrw
    

    Output:

    Host: https://gitlab.git.nrw/
    Token: [stored]
    
Multiple Hosts

Add additional instances:

divekit config set @hosts gitlab-com https://gitlab.com/ --token glpat-yyy...

Member List Configuration

  • DIVEKIT_MEMBERS: Optional environment variable for the default path to members.json.

    Set it as a system environment variable:

    Linux/macOS

    Add to ~/.bashrc or ~/.zshrc:

    export DIVEKIT_MEMBERS="/path/to/members.json"
    

    Then:

    source ~/.zshrc
    
    Windows

    Add via System Properties > Environment Variables > User Variables:

    • Variable name: DIVEKIT_MEMBERS
    • Variable value: C:\path\to\members.json

    Alternatively, set per-distribution:

    divekit config set @origin.my-distribution.members.path "/path/to/members.json"
    

Security Notes

  • Tokens are stored in the operating system’s credential manager (Keychain on macOS, Credential Manager on Windows, Secret Service on Linux). ~/.divekit/hosts.json stores only host metadata and a token key reference.
  • Restrict permissions:
    chmod 600 ~/.divekit/hosts.json  # Linux/macOS
    
  • Use minimal scopes (api for full access, read_api for read-only).
  • For CI/CD, use temporary tokens or pipeline variables (override with GITLAB_TOKEN env var).
  • hosts.json is ignored in .gitignore by default.
  • Avoid .env files for tokens; use config instead.

Verify Installation

Run the doctor command to verify your setup:

divekit doctor

This will check if:

  • Divekit is properly installed
  • Required environment variables are set
  • System requirements are met

Troubleshooting

If you encounter any issues:

  1. Run divekit doctor for detailed diagnostics
  2. Verify host configuration: divekit config get @hosts
  3. Check tokens in the OS keychain:
    • macOS: Keychain Access app > Search for “divekit-cli”
    • Windows: Credential Manager > Windows Credentials > Search for “divekit-cli”
    • Linux: secret-tool search divekit-cli <hostname>
  4. Check logs in ~/.divekit/logs
  5. Ensure correct permissions for ~/.divekit/ directory (chmod 700 ~/.divekit on Linux/macOS)

3 - First steps

First steps after installation

First Steps After Installation

Create Your First Assignment

  1. Create and navigate to a new directory:
mkdir my-assignment
cd my-assignment
  1. Initialize a new Divekit project:
divekit init

Assignment Content Creation

  1. Add your assignment files to the repository
  2. Mark solution parts in your code:
public class Example {
    //unsup
    return actualSolution;
    //unsup
}
  1. Add variables for individualization:
public class $EntityClass$ {
    // ...
}

Assignment Distribution

  1. Verify your setup:
divekit doctor
  1. Distribute the repositories:
divekit distribute

Next Steps

For more detailed information, please refer to:

  • Configuration options in the Configuration section
  • Detailed system requirements in the Prerequisites section

4 - Individualization

Learn how Divekit creates individualized programming assignments using variation.json and individualization.json configurations.

Overview

Divekit individualizes each student’s (or group’s) repository during distribution using two configuration files: variation.json and individualization.json. They define object/relationship variants, logic options, and per-member assignments β€” including structural changes, file selection by logic, and Lua-based customizations. Each distributed repository is unique while the core task stays consistent.

Configuration Files

Configs live in .divekit/distributions/<distribution-name>/:

  • variation.json: Declares available variations for objects, relations, and logic.
  • individualization.json: Assigns these variations to members (fixed or random) and sets per-member options.

They are created/copied during divekit init and can be edited directly or via divekit config.

variation.json Structure

The file lists arrays of objects, relations, and logic definitions:

{
  "objects": [{
    "ids": "Vehicle",
    "objectVariations": [
      {"name": "Car", "fields": [{"name": "speed", "type": "int", "values": ["100", "150"]}]},
      {"name": "Truck", "fields": [{"name": "weight", "type": "int", "values": ["2000", "3000"]}]}
    ]
  }],
  "relations": [{
    "id": "relation1", "type": "association", "source": "entity1", "target": "entity2",
    "options": ["one-to-one", "one-to-many"]
  }],
  "logic": [{
    "id": "logic1", "type": "businessLogic", "location": "src/logic",
    "options": ["simple", "complex"]
  }]
}
  • objects: Entity variations (e.g., class alternatives with fields).
  • relations: Relationship variants (e.g., multiplicities or types).
  • logic: Logic variants that select files or scripts (e.g., ShoppingCart_simple.java).

Variables may use placeholders like {{...}} or Lua for dynamic values.

individualization.json Structure

This file assigns variations to members and controls application:

{
  "version": "1.0",
  "logicId": "logic1",
  "objectAssignments": [
    {"memberId": "student1", "objectVariations": {"entity1": "Car"}, "relationOptions": {"relation1": "one-to-many"}},
    {"memberId": "student2", "objectVariations": {"entity1": "Truck"}, "randomLogic": true}
  ],
  "globalSettings": {"delimiter": "$", "warnUnresolved": true}
}
  • logicId: Global or per-member logic variant.
  • objectAssignments: Per-member object and relation choices (fixed or random).
  • globalSettings: Placeholder delimiter and unresolved-token warnings.

Without per-member overrides, values are chosen randomly from variation.json.

Individualization Process

Individualization runs during divekit distribute:

  1. Load variation.json and individualization.json.
  2. Resolve each member’s variation set (fixed or random).
  3. Generate content:
    • Replace placeholders (e.g., $EntityName$ β†’ “Car”).
    • Include/rename files by logic selection (e.g., _logic1).
    • Apply relation-driven code changes.
    • Run Lua for custom generation.
  4. Validate unresolved placeholders (warn if enabled).
  5. Create the new repo with the individualized content.

Using Placeholders

Placeholders in origin files are replaced during individualization:

public class $EntityName$ {
    private String name = "$DefaultName$";
    private int $AttributeName$ = $RandomNumber$;
    // Relation example
    public $RelatedEntity$ getRelated() {
        return related;
    }
}
  • $EntityName$: Selected object name (e.g., “Car”).
  • $DefaultName$: From object-variation fields.
  • Relations may generate extra code or files.

For logic variants, files like ShoppingCart_$LogicId$.java are renamed or included based on the selected logic.

Creating the Configuration Files

During divekit init

  • variation.json: Empty skeleton with default sections.
  • individualization.json: Copied from user config or created with defaults (optionally copied from another distribution).

Manual Editing

Edit both JSON files in .divekit/distributions/<name>/. Validate with divekit doctor.

individuals.json (optional)

Created during distribution to record assigned variations per member for reuse (e.g., patches). Not created at init.

Examples

Simple Object Variation

  • Define object “Person” with variations “Student” (age 18–25) and “Teacher” (30–50). Assign “Student” randomly to half the members. Result: corresponding class and fields per repo.

Logic Variant with Lua

  • Logic options “simple” vs “complex” with Algorithm_simple.java / Algorithm_complex.java. Lua generates data based on selected complexity.

Relation Individualization

  • Relation “hasFriend”: choose “one-to-one” or “one-to-many”. Fixed “one-to-many” yields list-based code.

Quality Assurance and Troubleshooting

  • Unresolved tokens: Use --warn-unresolved-tokens true to log warnings.
  • Validation: Run divekit doctor to check configs.
  • Dry runs: Use simulated provider (--provider simulated).
  • Reproducibility: Assigned variations persist in individuals.json (e.g., for late joiners).

Best Practices

  • Start simple; grow complexity gradually.
  • Use Lua for advanced generation.
  • Test with a small member list first.
  • Document variation IDs and logic options.
  • Provide fallbacks to avoid unresolved tokens.

For advanced setups, see the full schema in code or the RE docs under docs/re.

5 - Distribution

Learn how Divekit distributes programming assignments to students.

Overview

Divekit can distribute your assignment to multiple repositories on GitLab, creating individualized versions for each student or group. This process includes:

  • Creating code repositories for each student/group
  • Optionally creating secure pipeline repositories for automated testing
  • Assigning the correct permissions to students
  • Individualizing the content based on your configuration
  • Setting up automated CI/CD pipelines

Initialize Distribution

Before you can distribute assignments, you need to initialize a distribution configuration:

divekit init

This command will guide you through creating a new distribution and create a .divekit/distributions/<name>/config.json file in the current directory.
The distribution name is used to identify the distribution configuration.

Distribution Guide

After initializing your distribution, use the distribute command to start the distribution process:

divekit distribute 

Or with the --distribution flag:

divekit distribute --distribution <distribution-name>

The command will:

  1. Load or prompt for the specified distribution configuration
  2. Ask for members to process
  3. Check if all configured members exist on GitLab
  4. Show you a summary of what will be created
  5. Create the repositories after your confirmation

Example Flow

# First, initialize a new distribution
$ divekit init
[interactive prompts for configuration...]

# Then distribute the assignment
$ divekit distribute --distribution my-assignment

--- Distribution Plan ---
Distribution Name: my-assignment

Target: https://gitlab.git.nrw/
  - Repo Name Template: assignment-{{uuid}}
  - Target Group ID: 12345
  - Members to process: 5 members across 2 groups

Would create 2 repositories with name "assignment-{{uuid}}" and assign 5 members.
Secure pipeline enabled - will also create sandbox repositories.

? Continue? [Y/n]: y

Creating main repositories at group #234567:
[β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ] 100% (2/2)

Creating secure pipeline repositories at group #345678:
[β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ] 100% (2/2)

Setting up repository linking (main ↔ sandbox):
[β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ] 100% (2/2)

Assigning members:
[β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ                         ] 50% (1/2)

What Happens During Distribution?

  1. Divekit creates a new code repository for each student/group
  2. If secure pipeline is enabled, sandbox repositories are created in a separate group
  3. Repository contents are individualized based on your variable configuration
  4. Students are assigned with appropriate permissions (developer/maintainer)
  5. Repository linking is established between code and sandbox repositories
  6. CI/CD pipelines are configured for automated testing
  7. Each repository gets a unique identifier via UUID

Next Steps

6 - Glossary

Comprehensive list of Divekit terms and definitions.

This glossary provides definitions for terms used throughout the Divekit documentation.

TermDefinition
DivekitA command-line tool for managing individualized programming assignments at scale.
CLICommand Line Interface - the primary way to interact with Divekit.
Origin RepositoryThe source repository containing the assignment template and Divekit configuration.
DistributionA specific configuration for creating and managing student repositories.
IndividualizationThe process of creating unique variations of assignments for each student.
Secure PipelineOptional test repositories that run automated evaluations separately from student code.
MembersStudents or users who will receive access to distributed repositories.
UUIDUniversally Unique Identifier - used to create unique repository names.
LinkingThe connection between code and test repositories in secure pipeline setups.
VariablesPlaceholders in assignment files that are replaced with random values during individualization.
RemoteConfiguration for connecting to different GitLab instances or environments.