Ivet 1.8.7

dotnet tool install --global Ivet --version 1.8.7
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local Ivet --version 1.8.7
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=Ivet&version=1.8.7
                    
nuke :add-package Ivet --version 1.8.7
                    

Summary

Ivet is a command line tool created to generate a schema for a janusgraph database and apply this schema. It has been inspired from Doctrine behaviour. The generate command creates a json file containing commands to execute. The file can be manually modified if you find migration is not complete or does not cover all you deserves. To keep trace of all applied migrations, migration names are saved into janusgraph server when upgrade is called. You can check at any moment the list of migrations both applied and not.

Available commands

  • generate
    • dir Dlls to analyze. If not set look in current working directory.
    • output Directory where to put migration file. If not set files are created in current directory.
    • ip localhost
    • port 8182
    • ssl Use SSL/TLS for JanusGraph connection (default: false)
    • sprintno Add a subdirectory when generating. Use it as you want
    • onefile Create one file per script
    • description Add a description to your migration
  • list Display list of all migrations
    • input Directory where to find migration files. If not set look in current working directory.
    • ip localhost
    • port 8182
    • ssl Use SSL/TLS for JanusGraph connection (default: false)
  • upgrade
    • input Can be a file or a directory containing migrations to be applied. If not set look in current working directory.
    • ip localhost
    • port 8182
    • ssl Use SSL/TLS for JanusGraph connection (default: false)
    • timeout Default evaluation timeout in milliseconds for Gremlin scripts. Can be overridden per script or per migration file in JSON
    • no-verify Skip post-upgrade index status verification (default: false — verify runs on every upgrade, even with no migrations to apply)
  • status Display all JanusGraph indices with per-key status (ENABLED / INSTALLED / REGISTERED)
    • ip localhost
    • port 8182
    • ssl Use SSL/TLS for JanusGraph connection (default: false)
    • fail-on-non-enabled Exit with code 1 if any index key is not ENABLED (useful in CI/CD)
  • reindex Force REGISTER + REINDEX on one or all stuck indices
    • index Target index name. If omitted, all non-ENABLED indices are reindexed.
    • await-enabled Wait for ENABLED status after REINDEX (long operation, default: false)
    • timeout-seconds Per-step await timeout in seconds (default: 300)
    • ip localhost
    • port 8182
    • ssl Use SSL/TLS for JanusGraph connection (default: false)

Docker image

Docker image is available there:

To use Docker image, run the following command replacing MyDir with your local directory

docker run -v MyDir:/app/Migrations -e ip=localhost ivet

See upgrade command to add your own parameters.

Dotnet Tool

You can install Ivet as a dotnet tool

dotnet tool install --global Ivet

All versions are available on https://www.nuget.org/packages/Ivet

After the package is installed you can use it like

Ivet list --input "C:\MigrationFiles"

How to tag code?

Add Ivet.Model (https://www.nuget.org/packages/Ivet.Model) to your project. You are now ready to tag your code. All names and possibilities are listed in Janusgraph documentation at https://docs.janusgraph.org/schema/.

Tag a Vertex:

[Vertex]
public class MyVertex
{
    [PropertyKey]
    [PrimaryKey()]
    public string Id { get; set; }

    [PropertyKey(Name="NewName", Cardinality=Cardinality.SINGLE)]
    public string ANamedProperty { get; set; }

    [EdgeProperty]
    public List<Vertex3> AListProperty { get; private set; } = new List<Vertex3>();

    [EdgeProperty]
    public Vertex3[] AnArrayProperty { get; private set; } = Array.Empty<Vertex3>(); 
}

You can also specify a different name or a cardinality (details at https://docs.janusgraph.org/schema/#property-key-cardinality):

[PropertyKey(Name="NewName", Cardinality=Cardinality.SINGLE)]
public string ANamedProperty { get; set; }

Tag an Edge:

[Edge(typeof(MyVertex1), typeof(MyVertex2))]
[Edge(typeof(MyVertex1), typeof(MyVertex3))]
public class EdgeWithProperties
{
    [PropertyKey]
    public int AProperty { get; set; }
}

You can also tag a property to be used with an index (https://docs.janusgraph.org/schema/index-management/index-performance/):

[Vertex]
public class MyVertex
{
    [PropertyKey]
    [CompositeIndex("unicity_index", IsUnique = true)] // Set unicity of the data
    public string ACompositeIndexProperty { get; set; }

    [PropertyKey]
    [MixedIndex("vertex2_mixed", Backend = "search", Mapping = MappingType.TEXTSTRING)]
    public string SearchProperty { get; set; }
}

Mixed index with shared properties (inheritance)

When multiple vertex types inherit the same [MixedIndex] property from an abstract base class, Ivet detects that the index spans several vertex labels and generates a global mixed index (without indexOnly). The search backend will index the property on all vertex types that carry it, and the hasLabel() step in queries still filters efficiently.

If only one vertex type uses a given index name, the generated script uses indexOnly(vertex) as before.

public abstract class AbstractItem
{
    [PropertyKey]
    [MixedIndex("search", Backend = "search", Mapping = MappingType.TEXT)]
    public string Name { get; set; }

    [PropertyKey]
    [MixedIndex("search", Backend = "search", Mapping = MappingType.STRING)]
    public string Code { get; set; }
}

[Vertex]
public class ConcreteItemA : AbstractItem { }

[Vertex]
public class ConcreteItemB : AbstractItem { }
// → Ivet generates one global "search" index with Name (TEXT) + Code (STRING)

Mapping types: | MappingType | Behavior | |-------------|----------| | TEXT | Tokenized — splits on spaces, hyphens, etc. Good for natural text | | STRING | Not tokenized — the entire value is compared as-is. Good for codes and identifiers | | TEXTSTRING | Both tokenized and exact match |

Timeout & Resilience

Index operations (awaitGraphIndexStatus, REINDEX) can take a long time. By default, generated index scripts include a 5-minute evaluation timeout (300000 ms).

You can control the timeout at three levels (highest priority first):

  1. Per script in JSON: "evaluationTimeout": 600000 inside a script entry
  2. Per file in JSON: "evaluationTimeout": 600000 at the migration file level
  3. CLI flag: --timeout 600000 on the upgrade command
Ivet upgrade --input ".\Migrations" --timeout 600000

If an index script times out, the migration is still marked as applied. JanusGraph registers the index operation and will complete it on restart. Re-running the same script would fail with "index already exists". Scripts without an explicit timeout (e.g., entity creation scripts) are NOT marked as applied on timeout — the error propagates normally.

Index health: status, reindex, verify

After an upgrade, Ivet automatically verifies that every index key is in the ENABLED state. If one is stuck (INSTALLED or REGISTERED), the command exits with code 1 and logs the offending keys. Pass --no-verify to opt out.

Use status at any time to inspect the cluster:

Ivet status --ip localhost --port 8182

In CI/CD, you can also run it as a dedicated gate:

Ivet upgrade --input ./Migrations
Ivet status --fail-on-non-enabled

If an index is stuck, use reindex to unblock it. Without --index, it targets every non-ENABLED index (useful in CI/CD where you don't know the name up front):

Ivet reindex --index search --await-enabled --timeout-seconds 600
Ivet reindex                                                    # reindex all stuck indices

The flow per index is REGISTER_INDEX → await REGISTERED → REINDEX → (optional) await ENABLED, with idempotent guards: already-ENABLED indices are skipped.

What's next?

You can now run a generate command in order to create migration files.

Many files are created by the generate command. One contains vertices and edges and properties. Indices are in different files to avoid timeout at migration time.

You can have some details of migrations with list.

You can open and manually edit your migration files. In particular there is a description field whose content can be seen with list command

> Ivet list --input ".\Migrations"

Directory: D:\Migrations

Migrations:
 --------------------------------------------------------------------------------------------------------------------------
 | Name                      | Relative path                  | Description | Date                | Multi? | Timeout  |
 --------------------------------------------------------------------------------------------------------------------------
 | Migration_202403032330_#0 | 12\Migration_202403032330.json | [0]         | 10/03/2024 14:21:54 | True   |          |
 --------------------------------------------------------------------------------------------------------------------------
 | Migration_202403032330_#1 | 12\Migration_202403032330.json | [1]         | 10/03/2024 14:22:04 | True   | 300000ms |
 --------------------------------------------------------------------------------------------------------------------------
 | Migration_202403032330_#2 | 12\Migration_202403032330.json | [2]         | 10/03/2024 14:22:14 | True   | 300000ms |
 --------------------------------------------------------------------------------------------------------------------------

 Count:3
Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated
1.8.7 121 4/21/2026
1.8.5 112 4/13/2026
1.8.4 117 3/27/2026
1.8.3 109 3/26/2026
1.8.2 112 3/26/2026 1.8.2 is deprecated because it has critical bugs.
1.8.1 109 3/7/2026
1.8.0 123 2/26/2026 1.8.0 is deprecated because it has critical bugs.
1.7.3 240 10/30/2025
1.7.2 236 9/28/2025
1.7.0 225 9/25/2025
1.6.1 209 4/5/2025
1.5.1 164 1/14/2025
1.5.0 199 11/7/2024
1.4.0 192 10/26/2024
1.3.0 247 4/24/2024 1.3.0 is deprecated because it is no longer maintained.
1.2.0 295 3/10/2024 1.2.0 is deprecated because it is no longer maintained.
1.1.1 297 3/4/2024 1.1.1 is deprecated because it is no longer maintained.
Loading failed

* Add global index for abstract classes
* Add specific index for sub classes
* Add reindex command