CLI integration
The ItTiger.TigerQuery.CliCore
package adds a reusable connection command group to applications built with
TigerCli. It provides
list, show, add, edit, and delete commands backed by
ItTiger.TigerQuery.Core.
Install it with:
dotnet add package ItTiger.TigerQuery.CliCore
The public composition surface is deliberately small: SqlServerConnectionCommands, SqlServerConnectionCommandOptions, TigerQueryCliContribution, and TigerQueryCliOptions. Individual command handlers, settings models, writers, and resource implementations are internal and are not part of this API reference.
using ItTiger.TigerCli.Commands;
using ItTiger.TigerQuery.CliCore;
using ItTiger.TigerQuery.Core;
// One instance, shared by the contribution and every consumer of connections.
var tigerQuery = new TigerQueryCliContribution(new TigerQueryCliOptions
{
DefaultConnectionStoreFile =
SqlServerConnectionStoreOptions.AppSpecific("YourVendor", "your-tool").FilePath,
DefaultE2eBootstrapConnectionName = "your-tool-e2e"
});
var app = TigerCliApp.CreateBuilder()
.UseAssemblyMetadata(typeof(Program).Assembly)
.UseAppResources(SqlServerConnectionCommands.CreateAppResources())
.AddContribution(tigerQuery)
.AddCommandGroup("connection", group =>
{
group.SetDescription("Manage saved connections");
SqlServerConnectionCommands.Configure(group, options =>
{
options.TigerQuery = tigerQuery.Options;
options.ValidationPolicy =
SqlServerConnectionValidationPolicy.DatabaseOptional;
});
})
.AddCommand("run", () => new RunCommand(tigerQuery.Options), "Run a script.")
.Build();
return await app.RunAsync(args);
The host application retains control of themes, cultures, other commands, and exit-code mapping. Connection commands return portable semantic TigerCli exit kinds such as success, validation error, not found, and already exists.
Letting a run select the store
Registering the contribution gives the application a standard
--tq-connection-store-file <path> option and TIGERQUERY_CONNECTION_STORE_FILE
support, so one run can work against a different store without a per-tool
option name or precedence rule. Precedence and validation belong to
ItTiger.TigerQuery.Core;
this package only carries the value across and reports failures as TigerCli
validation errors.
Registering the contribution and mounting the connection group are separate
opt-ins — either works without the other. The rule that matters is to create the
TigerQueryCliOptions once and give that same instance to
AddContribution, to options.TigerQuery, and to the application's own command
factories and services. Two instances leave the run resolving a path that
nothing reads.
TigerCli applies the option once per run, before command settings are bound, so
a bad path ends the run cleanly rather than failing inside a handler. Help
rendering invokes no callback, so help text can use
DefaultConnectionStoreFile but never the resolved path. The store is built
lazily on first use of TigerQueryCliOptions.Store and then reused for the rest
of the run, so the commands, the providers, the edit loader, and host services
all share one instance — one file, one lock, one mutation gate.
options.TigerQuery is the only way to give the group a store. There is
deliberately no composition-time property that pins an already-constructed
SqlServerConnectionStore, because such a store would ignore whatever the run
selected; a group configured without it is rejected when the group is
configured. See
Selecting one store.
Localization and metadata
CreateAppResources(params ResourceManager[]) creates a chained resource
manager. Host resources are consulted first, followed by the built-in en-US and
pl-PL connection-command strings.
CliCore uses TigerCli 0.9.2's resource-key overloads for both the contributed
--tq-connection-store-file description and the
TIGERQUERY_CONNECTION_STORE_FILE entry shown by --help-env. They are therefore
resolved using the run culture at help-render time. The supplied English text remains
the fallback, and no TigerQuery-specific localization workaround is required.
The add and edit commands accept repeatable metadata mutations. The list
command accepts repeatable value, key-present, and key-absent filters; every
filter must match. Metadata is application-owned, case-sensitive, excluded from
connection strings, and must not contain secrets. Generic set/remove operations
reject the lowercase ittiger.e2e.* namespace because it is reserved for
TigerQuery-owned metadata; list filters and reads remain forward-compatible with
unknown reserved keys.
Creating E2E-authorized profiles
The regular add command can authorize a new profile for E2E use without making it the host's bootstrap profile:
your-tool connection add test-server --server sql01 --e2e
your-tool connection add test-creator --server sql01 --e2e --allow-database-create
--e2e writes exactly ittiger.e2e.enabled=true.
--allow-database-create additionally writes exactly
ittiger.e2e.allow-database-create=true and is rejected unless --e2e is also
present. Both are non-promptable switches. Regular --e2e never writes
ittiger.e2e.bootstrap. A resolver therefore rejects one of these profiles as
bootstrap even when its name matches the expected name.
The dedicated bootstrap creation command is:
your-tool connection add-e2e-bootstrap [--name <name>] --server <server>
An explicit --name wins. Otherwise CliCore uses the host's
DefaultE2eBootstrapConnectionName. If neither supplies a usable name, the
command returns a validation error before opening or creating the selected
store, its directory, or a partial profile. The command always writes the E2E
authorization flag and ittiger.e2e.bootstrap=true, and accepts the same
connection, prompting, validation, and persistence options as regular add;
--allow-database-create remains a separate explicit permission. The name
identifies the expected profile and metadata authorizes it as bootstrap; both
are required during resolution.
Bootstrap profiles created by older builds lack the new bootstrap flag and now
fail resolution as invalid. After preserving any settings still needed, delete
and recreate such a profile with add-e2e-bootstrap; generic --metadata
writes cannot add the flag because all ittiger.e2e.* keys remain reserved.
Configuring external values
The three connection-writing flows (add, edit, and
add-e2e-bootstrap) expose exactly five non-promptable reference options:
--server-reference <json>
--database-reference <json>
--username-reference <json>
--password-reference <json>
--connection-string-reference <json>
Their JSON is Core's persisted reference object, not a value wrapper invented
by the CLI. Environment-variable, whole-text-file, and keyed-JSON-file forms are
documented under External profile values.
Reference options reject JSON string literals, and sensitive connection-string
keys cannot be supplied through --opt, so the automation path does not expose
plaintext credentials in process arguments.
For a fully non-interactive SQL-auth bootstrap:
your-tool connection add-e2e-bootstrap --non-interactive --authentication SqlPassword --server-reference {environment-reference-json} --username-reference {keyed-file-reference-json} --password-reference {text-file-reference-json}
Use --connection-string-reference by itself for full-string mode. It is
strictly mutually exclusive with field-based settings, including authentication,
encryption, pooling, and --opt. Validation failures occur before persistence.
Unrelated edits preserve reference objects, and inspection renders only source
descriptions without resolving external values.