-
Notifications
You must be signed in to change notification settings - Fork 14
Id Generator CLI
Use the Id Generator CLI (idgen) to generate Id<T> definitions for DataverseUnitTest from the command line or from AI coding assistants such as Cursor.
This complements the Id Generator WinForms tool and reuses the same parsing and output logic.
| Tool | Best for |
|---|---|
WinForms app (IdGenerator/) |
Interactive use, visual settings, parse/regenerate from output |
CLI (IdGenerator.Cli/) |
Scripts, CI, terminal workflows, AI assistants |
Cursor skill (.cursor/skills/generate-ids/) |
In-repo guidance for Cursor agents |
The CLI and WinForms app share the same core library (IdGenerator.Core/).
Install the global idgen tool:
dotnet tool install -g DataverseUnitTest.IdGenerator.CliThen run:
idgen --input "Account 2|Contact"- NuGet package: DataverseUnitTest.IdGenerator.Cli
- Requires: .NET 10 SDK or runtime (or newer)
Pin a specific version:
dotnet tool install -g DataverseUnitTest.IdGenerator.Cli --version 1.0.0.1Update or uninstall:
dotnet tool update -g DataverseUnitTest.IdGenerator.Cli
dotnet tool uninstall -g DataverseUnitTest.IdGenerator.CliIf you are working in the source repo and have not installed the global tool, from the repository root:
dotnet run --project IdGenerator.Cli -- --settings-file .cursor/IdGeneratorSettings.json --input "Account 2|Contact"dotnet pack IdGenerator.Cli/IdGenerator.Cli.csproj -c Release
dotnet tool install -g --add-source IdGenerator.Cli/bin/Release DataverseUnitTest.IdGenerator.CliGitHub releases may also include a pre-built tool package (IdGenerator.Cli.zip).
idgen [input] [options]
| Option | Description |
|---|---|
[input] |
Entity definitions as a positional argument. Use | instead of newlines on the command line. |
-i, --input <text>
|
Entity input text. Preferred on PowerShell when quoting complex input. |
-f, --input-file <path>
|
Read entity input from a file. |
If no input option is provided and stdin is redirected, entity input is read from stdin.
| Option | Description |
|---|---|
--from-csharp <path|-> |
Parse existing C# Id<T> definitions, preserve structure, regenerate GUIDs. Use - for stdin. |
| Option | Description |
|---|---|
--seed [int] |
Use deterministic GUIDs. Default seed is 1 when the flag is used without a value. |
--settings-file <path> |
Load options from IdGeneratorSettings.json. |
--use-class-ids |
Generate nested *Ids classes (default). |
--use-struct-ids |
Generate struct-based IDs. |
--use-target-typed-new |
Use new("GUID") syntax (default). |
--use-explicit-new |
Use new Id<T>("GUID") syntax. |
-h, --help
|
Show help. |
| Code | Meaning |
|---|---|
0 |
Success |
1 |
Error (invalid input, parse failure, etc.) |
2 |
Help displayed |
Each non-empty line defines IDs for one Early Bound entity/table. See Id Generator for full background on the WinForms tool.
On the command line, | is treated the same as a newline. This makes multi-entity input easier to type:
Account 2|Contact,Partners,Jim,Bob
is equivalent to:
Account 2
Contact,Partners,Jim,Bob
In input files (--input-file), use normal newlines. Pipes are optional.
<EntityType> [Count]
-
Countis optional; if omitted, one ID is generated. - If
Countis greater than1, a collection is generated with auto namesA,B,C, ...
Examples:
Account
Account 2
<EntityType>,<NameOrCollection>[,<IdName1>,<IdName2>...]
- If there are exactly 2 comma-separated values, the second value is either a single ID/property name or a collection name (if followed by a count, e.g.
Contact,Employees 2). - If there are 3+ comma-separated values, the second value is the collection name and remaining values are explicit ID names.
- Do not put spaces after commas inside comma-based tokens.
Examples:
Acme_ProjectTask,Task
Contact,Partners,Jim,Bob
Contact,Employees 2
Acme_Project 2
Acme_ProjectTask,Task
Contact,Partners,Jim,Bob
Account 2
Or on one CLI line:
Acme_Project 2|Acme_ProjectTask,Task|Contact,Partners,Jim,Bob|Account 2
public Id<Acme_ProjectTask> Task { get; } = new("C9E8361B-AC23-4134-B242-C52BDFD56A9F");
public AccountIds Accounts { get; } = new();
public PartnerIds Partners { get; } = new();
public ProjectIds Projects { get; } = new();
public class AccountIds
{
public Id<Account> A { get; } = new("9B046FDF-94AF-4F4A-85C4-CD7F7F984367");
public Id<Account> B { get; } = new("4CA2375F-5287-494D-8E30-4DFD1CF2F9E7");
}
public class PartnerIds
{
public Id<Contact> Bob { get; } = new("C46E99ED-F28E-48FF-9EFB-6B7516CDB99D");
public Id<Contact> Jim { get; } = new("C7F251B1-6D2A-4A28-BA07-8D3F781A1D6A");
}
public class ProjectIds
{
public Id<Acme_Project> A { get; } = new("4D67154A-0A50-4C3E-8D55-0FE93BE4F3DC");
public Id<Acme_Project> B { get; } = new("E804C340-1C9D-41D7-930F-64B730B3373E");
}- Output entries are ordered by container name; single IDs (no container) are emitted first.
- Names inside each generated collection are ordered alphabetically.
- Entity names with
_use the part after_when generating default property names (e.g.Acme_Project→Project,Projects).
- Identify the Early Bound entity types needed.
- Build entity input (one line with
|is fine for CLI use). - Run the CLI and capture stdout.
- Paste the generated properties/classes into a nested helper class in your test.
idgen --settings-file .cursor/IdGeneratorSettings.json --input "Account|Contact 2|SystemUser"Use this when you want new GUIDs but the same property/class structure:
idgen --settings-file .cursor/IdGeneratorSettings.json --from-csharp path/to/MyTest.csFrom stdin (PowerShell):
Get-Content path/to/snippet.cs | idgen --settings-file .cursor/IdGeneratorSettings.json --from-csharp -From stdin (bash):
idgen --settings-file .cursor/IdGeneratorSettings.json --from-csharp - < snippet.csUse --seed when you need reproducible GUIDs:
idgen --seed 42 --settings-file .cursor/IdGeneratorSettings.json --input "Account 2"Without --seed, GUIDs are random (normal test usage).
idgen --settings-file .cursor/IdGeneratorSettings.json --input-file entities.txtExample entities.txt:
Account 2
Contact,Partners,Jim,Bob
SystemUser
Settings can be loaded from a JSON file:
{
"useTargetTypedNew": true,
"useClassIds": true
}The repository includes a default file at .cursor/IdGeneratorSettings.json.
| Setting | Default | Description |
|---|---|---|
useClassIds |
true |
Generate class-based nested *Ids types instead of structs. |
useTargetTypedNew |
true |
Use target-typed new("GUID") instead of new Id<T>("GUID"). |
entities |
(sample) | Used by the WinForms app; ignored by CLI unless you reuse the same file. |
CLI flags override settings file values for the current run.
AI assistants should run the CLI rather than inventing GUIDs or naming rules by hand.
If the global tool is installed from NuGet:
idgen --settings-file .cursor/IdGeneratorSettings.json --input "Account 2|Contact"When working in the source repository without the global tool installed:
dotnet run --project IdGenerator.Cli -- --settings-file .cursor/IdGeneratorSettings.json --input "Account 2|Contact"This repository includes a Cursor skill at:
.cursor/skills/generate-ids/SKILL.md
That skill tells Cursor agents:
- When to generate test IDs
- Which command to run
- How to format entity input
- How to use
--from-csharpand--seed
Clone or copy that skill into other projects if needed.
- Determine required entity types and counts from the test being written.
- Build entity input using the formats above.
- Run
idgen(install from NuGet withdotnet tool install -g DataverseUnitTest.IdGenerator.Cli, or usedotnet run --project IdGenerator.Cliwhen working in the source repo). - Paste stdout into the test's nested IDs helper class.
- Do not manually create GUIDs or guess container/property naming.
Match patterns used elsewhere in the test project, such as nested TestIdsClass / *Ids containers.
Input:
Contact 4
Output:
public ContactIds Contacts { get; } = new();
public class ContactIds
{
public Id<Contact> A { get; } = new("...");
public Id<Contact> B { get; } = new("...");
public Id<Contact> C { get; } = new("...");
public Id<Contact> D { get; } = new("...");
}idgen --input "Account|Contact 4|SystemUser 2"idgen --use-struct-ids --input "Contact 2"idgen --use-explicit-new --input "Account"Inside double quotes, | is a literal character. Prefer --input for clarity:
idgen --input "Account 2|Contact"Avoid unquoted input containing |, which PowerShell may interpret as the pipeline operator.
Provide one of:
- positional input
--input--input-file--from-csharp- redirected stdin
The --from-csharp input must contain parseable Id<T> properties or fields in the supported formats (class properties, nested classes, structs, or top-level properties).
The WinForms app saves settings next to its executable (IdGeneratorSettings.json). The CLI uses the path from --settings-file, or defaults next to the CLI executable if no file is specified.
- Id Generator — WinForms tool and input format reference
- DataverseUnitTest.IdGenerator.Cli on NuGet.org
- Repository:
IdGenerator/,IdGenerator.Core/,IdGenerator.Cli/ - GitHub releases — WinForms zip and CLI tool package