{"id":21408542,"url":"https://github.com/dotnetconfig/dotnet-config","last_synced_at":"2025-05-16T05:08:16.304Z","repository":{"id":40304789,"uuid":"240983987","full_name":"dotnetconfig/dotnet-config","owner":"dotnetconfig","description":"A global tool and accompanying API for managing hierarchical configurations for dotnet tools, using git config format","archived":false,"fork":false,"pushed_at":"2025-03-18T13:20:26.000Z","size":1264,"stargazers_count":79,"open_issues_count":2,"forks_count":7,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-05-10T04:06:46.118Z","etag":null,"topics":["cli","configuration","dotnet","tool"],"latest_commit_sha":null,"homepage":"https://dotnetconfig.github.io/dotnet-config","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dotnetconfig.png","metadata":{"files":{"readme":"readme.md","changelog":"changelog.md","contributing":"contributing.md","funding":null,"license":"license.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"devlooped"}},"created_at":"2020-02-16T23:38:46.000Z","updated_at":"2025-04-29T15:45:30.000Z","dependencies_parsed_at":"2024-01-13T17:38:03.697Z","dependency_job_id":"c6647277-03f0-4312-b570-a851054709bb","html_url":"https://github.com/dotnetconfig/dotnet-config","commit_stats":{"total_commits":237,"total_committers":8,"mean_commits":29.625,"dds":"0.33755274261603374","last_synced_commit":"11634a5b02d6a70cac0980f809be2a696f5ed565"},"previous_names":["kzu/dotnet-config"],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dotnetconfig%2Fdotnet-config","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dotnetconfig%2Fdotnet-config/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dotnetconfig%2Fdotnet-config/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dotnetconfig%2Fdotnet-config/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dotnetconfig","download_url":"https://codeload.github.com/dotnetconfig/dotnet-config/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254471058,"owners_count":22076585,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","configuration","dotnet","tool"],"created_at":"2024-11-22T17:16:48.116Z","updated_at":"2025-05-16T05:08:11.295Z","avatar_url":"https://github.com/dotnetconfig.png","language":"C#","funding_links":["https://github.com/sponsors/devlooped","https://github.com/sponsors"],"categories":[],"sub_categories":[],"readme":"![Icon](https://raw.githubusercontent.com/dotnetconfig/dotnet-config/main/docs/img/icon-32.png) dotnet-config\n============\n\n[![CLI NuGet](https://img.shields.io/nuget/v/dotnet-config.svg?label=nuget.cli\u0026color=royalblue)](https://www.nuget.org/packages/dotnet-config) [![API NuGet](https://img.shields.io/nuget/v/DotNetConfig.svg?label=nuget.api\u0026color=royalblue)](https://www.nuget.org/packages/DotNetConfig) [![Downloads](https://img.shields.io/nuget/dt/DotNetConfig?color=darkmagenta)](https://www.nuget.org/packages/DotNetConfig) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/dotnetconfig/dotnet-config/blob/main/license.txt) [![Discord Chat](https://img.shields.io/badge/chat-on%20discord-7289DA.svg)](https://discord.gg/x4qhjYd) [![GitHub](https://img.shields.io/badge/-github-181717.svg?logo=GitHub)](https://github.com/dotnetconfig/dotnet-config) \n\n[![CI Version](https://img.shields.io/endpoint?url=https://shields.kzu.io/vpre/dotnet-config/main\u0026label=nuget.ci\u0026color=brightgreen)](https://pkg.kzu.io/index.json) [![CI Status](https://github.com/dotnetconfig/dotnet-config/workflows/build/badge.svg?branch=main)](https://github.com/dotnetconfig/dotnet-config/actions?query=branch%3Amain+workflow%3Abuild+)\n\n\u003cp\u003e\n\u003cb\u003e\u003ca href=\"#why\"\u003eWhy\u003c/a\u003e\u003c/b\u003e\n|\n\u003cb\u003e\u003ca href=\"#what\"\u003eWhat\u003c/a\u003e\u003c/b\u003e\n|\n\u003cb\u003e\u003ca href=\"#who\"\u003eWho\u003c/a\u003e\u003c/b\u003e\n|\n\u003cb\u003e\u003ca href=\"#how\"\u003eHow\u003c/a\u003e\u003c/b\u003e\n|\n\u003cb\u003e\u003ca href=\"#format\"\u003eFormat\u003c/a\u003e\u003c/b\u003e\n|\n\u003cb\u003e\u003ca href=\"#api\"\u003eAPI\u003c/a\u003e\u003c/b\u003e\n|\n\u003cb\u003e\u003ca href=\"#cli\"\u003eCLI\u003c/a\u003e\u003c/b\u003e\n\u003c/p\u003e\n\n\u003c!-- #content --\u003e\n# Why\n\n`dotnet-config` (or `.netconfig`) provides a uniform mechanism for \n[.NET Core tools](https://docs.microsoft.com/en-us/dotnet/core/tools/global-tools) to store and \nread configuration values in a predictable format which can be manipulated through a command \nline tool, an API and also manually in any text editor by the user.\n\nJust like [git config](https://git-scm.com/docs/git-config) provides a uniform way of storing \nsettings for all git commands, the goal of `dotnet-config` is to foster the same level of \nconsistency across all .NET tools. The format is (mostly) compatible with it too and therefore \nleverages the learnings of the git community around configuration for arbitrary tools.\n\n# What\n\n`dotnet-config` provides the following:\n* A well-documented file format than can be hand-edited in any text editor.\n* A dotnet global tool to manage the configuration files (much like [git config](https://git-scm.com/docs/git-config)).\n* An API for dotnet tool authors to read/write settings.\n\nBy default, configuration files are named `.netconfig` and support four storage levels: \n* Local: a `.netconfig.user` file alongside the `Default` level.\n* Default: current directory and any ancestor directories.\n* Global: user profile directory, from [System.Environment.SpecialFolder.UserProfile](https://docs.microsoft.com/en-us/dotnet/api/system.environment.specialfolder?view=netstandard-2.0#fields).\n* System: system-wide directory, from [System.Environment.SpecialFolder.System](https://docs.microsoft.com/en-us/dotnet/api/system.environment.specialfolder?view=netstandard-2.0#fields).\n\nThe files are read in the order given above, with first value found taking precedence. \nWhen multiple values are read then all values of a key from all files will be returned.\n\n\u003e `.netconfig.user` can be used to keep local-only settings separate from team-wide settings \n\u003e in source control, and it's already a commonly ignored extension in \n\u003e [.gitignore](https://github.com/github/gitignore/blob/master/VisualStudio.gitignore#L9).\n\n# Who\n\nThe following are some of the tools that leverage *.netconfig* to provide flexible configuration persistence \noptions:\n\n[![dotnet-eventgrid](https://img.shields.io/nuget/v/dotnet-eventgrid.svg?color=royalblue\u0026label=dotnet-eventgrid)](https://dotnetconfig.org/who/dotnet-eventgrid)\n[![dotnet-file](https://img.shields.io/nuget/v/dotnet-file.svg?color=royalblue\u0026label=dotnet-file)](https://dotnetconfig.org/who/dotnet-file)\n[![dotnet-serve](https://img.shields.io/nuget/v/dotnet-serve.svg?color=royalblue\u0026label=dotnet-serve)](https://dotnetconfig.org/who/dotnet-serve)\n[![dotnet-vs](https://img.shields.io/nuget/v/dotnet-vs.svg?color=royalblue\u0026label=dotnet-vs)](https://dotnetconfig.org/who/dotnet-vs)\n[![reportgenerator](https://img.shields.io/nuget/v/dotnet-reportgenerator-globaltool.svg?color=royalblue\u0026label=reportgenerator)](https://dotnetconfig.org/who/reportgenerator)\n[![sleet](https://img.shields.io/nuget/v/sleet.svg?color=royalblue\u0026label=sleet)](https://dotnetconfig.org/who/sleet)\n\nLearn more about how the various tools leverage `.netconfig` in the [Who](https://dotnetconfig.org/who) \nsection of our docs site.\n\n\n# How\n\n## Format\n\nExample file:\n\n```gitconfig\n# .netconfig is awesome: https://dotnetconfig.org\n\n[serve]\n\tport = 8080\n\tgzip                    #shorthand for gzip=true\n\n[vs \"alias\"]\n\tcomexp = run|community|exp\n\tpreexp = run|preview|exp\n\n[file]\n\t# example of multi-valued variables\n\turl = https://github.com/dotnet/runtime/tree/master/docs/design/features\n\turl = https://github.com/dotnet/aspnetcore/tree/master/docs\n\n; subsections allow grouping variables\n[file \"docs/design/features/code-versioning.md\"]\n\turl = https://github.com/dotnet/runtime/blob/master/docs/design/features/code-versioning.md\n\tetag = 7405567...\n\n[file \"docs/APIReviewProcess.md\"]\n\turl = https://github.com/dotnet/aspnetcore/blob/master/docs/APIReviewProcess.md\n\tetag = 1e4acd7...\n\n[mytool]\n    description = \"\\t tab and \\n newline escapes, plus \\\\ backslash are valid\"\n    title = My tool is great    # internal whitespace preserved without needing double quotes\n    path = C:\\\\tool             # backslashes always escaped, inside or outside double quotes\n    size = 500kb                # numbers can have a multiplier (case insensitive) suffix kb, mb, gb, tb \n    max-size = 1T               # the 'b' is optional.\n    compress = true             # multiple variants for boolean: true|false|yes|no|on|off|1|0\n    secure   = yes\n    localized = off\n    enabled  = 1\n\n; array like syntax for complex objects\n[myArray \"0\"] # indecies must be unique\n    description = 1st item description\n    name = Fero\n[myArray \"1\"]\n    description = 2nd item description\n    name = Jozo\n```\n\nThe syntax follows closely the [git-config syntax](https://git-scm.com/docs/git-config#_syntax). \nThe `#` and `;` characters begin comments to the end of line, blank lines are ignored.\n\nThe file consists of **sections** and **variables**. A section begins with the name of the section in \nsquare brackets and continues until the next section begins. Section names are case-insensitive. \nOnly alphanumeric characters and `-` are allowed in section names. Each variable must belong \nto some section, which means that there must be a section header before the first setting of a \nvariable. \n\nSections can be further divided into **subsections**. To begin a subsection put its name in double \nquotes, separated by space from the section name, in the section header, like in the example below:\n\n```gitconfig\n[section \"subsection\"]\n```\n\nSubsection names are case sensitive and can contain any characters except newline. Doublequote `\"` \nand backslash `\\` can be included by escaping them as `\\\"` and `\\\\`, respectively. \n\nSection headers cannot span multiple lines. Variables may belong directly to a section \nor to a given subsection. You can have `[section]` if you have `[section \"subsection\"]`, but you \ndon't need to.\n\nAll the other lines are recognized as setting **variables**, in the form `name = value` (or just `name`, \nwhich is a short-hand to say that the variable is the boolean `true`). Variable names are case-insensitive, \nallow only alphanumeric characters and `-`, and must start with an alphabetic character. Variables may \nappear multiple times; we say then that the variable is *multivalued*.\n\nLeading whitespaces after `name =`, the remainder of the line after the first comment character `#`\nor `;`, and trailing whitespaces of the line are discarded unless they are enclosed in double quotes. \nInternal whitespaces within the value are retained verbatim.\n\nBackslash `\\` characters must always be escaped with `\\\\`. Double quotes must either be escaped with \n`\\\"` or be properly balanced, which causes the whitespace within to be preserved verbatim.\n\nBeside `\\\"` and `\\\\`, only `\\n` for newline character (NL) and `\\t` for horizontal tabulation (HT, TAB) \nescape sequences are recognized.\n\n\n\u003e NOTE: when using the CLI or API, these escaping rules are applied automatically\n\n### Values\n\nValues of many variables are treated as a simple string, but there are variables that take values of \nspecific types and there are rules as to how to spell them.\n\n* *boolean*\n\n\tWhen a variable is said to take a *boolean* value, many synonyms are accepted for `true` and \n\t`false`; these are all case-insensitive.\n\t\n\t* *true*: boolean true literals are `yes`, `on`, `true`, and `1`. Also, a variable defined without \n\t`=\u003cvalue\u003e` is taken as `true`.\n\n\t* *false*: boolean false literals are `no`, `off`, `false`, `0` and the empty string.\n\n* *datetime*\n\n\tVariables of this type are always parsed/written using ISO 8601 (or [round-trip](https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings#the-round-trip-o-o-format-specifier)) format.\n\n* *number*\n\n\tThe value for many variables that specify various sizes can be suffixed with `k`, `M`, `G` or `T` \n\tto mean\t\"scale the number by 1024\", \"by 1024x1024\", \"by 1024x1024x1024\" or \"by 1024x1024x1024x1024\"\n\trespectively. The suffix is case insensitive, and can also include the `b`, as in `kb` or `MB`.\n\n### Array of complex objects\n\nCreation of more complex objects in array is possible via subsections. Lets say that we have following configuration object:\n\n```csharp\npublic class WatchedProcess\n{\n    public string Name { get; set; }\n    public string ApplicationPath { get; set; }\n}\n```\n\nWe would like to retrieve from our configuration as `IList\u003cWatchedProcess\u003e`. Even if git-config syntax does not have direct support for this scenario, we are able to create list of complex object with subsection and [ConfigurationRoot](https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration.configurationroot?view=dotnet-plat-ext-6.0).\n\n`ConfigurationRoot` supports working with arrays by creating indices for items as \"subsections\". This allows us to create a section selector that picks values from the array based on the element index. For example, `WatchedProcess:0:Name` selects the value `Name` from the first item in the array. This means we can use indices as subsections and create an array of complex objects as follows:\n\n```gitconfig\n[WatchedProcesses \"0\"] # indicies must be unique\n\tApplicationPath = \"C:\\\\MyProcessPath\\ABCD\"\n\tName = NServiceBus.Host\n\n[WatchedProcesses \"1\"] # indicies must be unique\n\tApplicationPath = \"C:\\\\MyProcessPath2\\ABCD\"\n\tName = NServiceBus.Host\n\n[WatchedProcesses \"2\"] # indicies must be unique\n\tApplicationPath = \"C:\\\\MyProcessPath2\\ABCD\"\n\tName = NServiceBus.Host\n```\n\nWith this configuration we are able to retrieve array of complex objects in following way:\n```csharp\nvar configurationBuilder = new ConfigurationBuilder();\nconfigurationBuilder.AddDotNetConfig();\nvar configurationRoot = configurationBuilder.Build();\nvar watchedProcesses = configurationRoot.GetSection(nameof(WatchedProcess)).Get\u003cIList\u003cJson.Appsettings.WatchedProcess\u003e\u003e();\n```\n\n\u003e NOTE: be sure that your array items have unique index\n\n## API\n\nThere are three main ways to access *.netconfig* values:\n\n* [Native API](#native-api) for direct access to .netconfig values\n* [Microsoft.Extensions.Configuration](#microsoftextensionsconfiguration) provider\n* [System.CommandLine](#systemcommandline) for CLI apps\n\n### Native API\n\n[![Version](https://img.shields.io/nuget/v/DotNetConfig.svg?color=royalblue)](https://www.nuget.org/packages/DotNetConfig) [![Downloads](https://img.shields.io/nuget/dt/DotNetConfig.svg?color=darkmagenta)](https://www.nuget.org/packages/DotNetConfig)\n\n```\nPM\u003e Install-Package DotNetConfig\n```\n\nThe main usage for .NET tool authors consuming the [DotNetConfig](https://www.nuget.org/packages/DotNetConfig) \nAPI is to first build a configuration from a specific path (will assume current directory \nif omitted):\n\n```csharp\nvar config = Config.Build();\n```\n\nThe resulting configuration will contain the hierarchical variables set in the \ncurrent directory (or the given path), all its ancestor directories, plus global \nand system locations.\n\nWhen getting values, the supported primitives are exposed as first-class methods \nfor `Add`, `Get` and `Set`, so you get quite a few usability overloads for \neach of `Boolean`, `DateTime`, `Number` and `String`, such as `AddBoolean`, \n`GetDateTime`, `GetString` or `SetNumber`:\n\n```csharp\n// reads from:\n// [mytool]\n//   enabled = true\n\nbool? enabled = config.GetBoolean(\"mytool\", \"enabled\");\n\n// reads from:\n// [mytool.editor]\n//   path = code.exe\n\nstring? path = config.GetString(\"mytool.editor\", \"path\");\n\n\n// reads from:\n// [mytool \"src/file.txt\"]\n//   createdOn = 2020-08-23T12:00:00Z\n\nDateTime? created = config.GetDateTime(\"mytool\", \"src/file.txt\", \"createdOn\");\n// If value was not found, set it to the current datetime\nif (created == null)\n    // Would create the section if it did not previously exist, and add the variable\n    config.SetDateTime(\"mytool\", \"src/file.txt\", \"createdOn\", DateTime.Now);\n```\n\nAlternatively you can use the `TryGetXXX` methods instead, to avoid checking for \nnull return values in cases where the variable (in the requested section and \noptional subsection) is not found:\n\n```csharp\nif (!config.TryGetDateTime(\"mytool\", \"src/file.txt\", \"createdOn\", out created))\n    config.SetDateTime(\"mytool\", \"src/file.txt\", \"createdOn\", DateTime.Now);\n```\n\n\nSince `.netconfig` supports multi-valued variables, you can retrieve all entries as \n`ConfigEntry` and inspect or manipulate them granularly:\n\n```csharp\nforeach (ConfigEntry entry in config.GetAll(\"proxy\", \"url\"))\n{\n    // entry.Level allows inspecting the location where the entry was read from\n    if (entry.Level == ConfigLevel.System)\n        // entry came from Environment.SpecialFolder.System\n    else if (entry.Level == ConfigLevel.Global)\n        // entry came from Environment.SpecialFolder.UserProfile\n    else if (entry.Level == ConfigLevel.Local)\n        // entry came from .netconfig.user file in the current dir or an ancestor directory\n    else\n        // local entry from current dir .netconfig or an ancestor directory\n\n    Console.WriteLine(entry.GetString());\n    // entry.GetBoolean(), entry.GetDateTime(), entry.GetNumber()\n}\n```\n\nWhen writing values (via `AddXXX` or `SetXXX`) you can optionally specify the \nconfiguration level to use for persisting the value, by passing a `ConfigLevel`:\n\n```csharp\n// writes on the global .netconfig in the user's profile\n//[vs \"alias\"]\n//\tcomexp = run|community|exp\n\nconfig.AddString(\"vs\", \"alias\", \"comexp\", \"run|community|exp\", ConfigLevel.Global);\n```\n\nYou can explore the entire API in the [docs site](https://dotnetconfig.org/api/).\n\n### Microsoft.Extensions.Configuration\n\n[![Version](https://img.shields.io/nuget/v/DotNetConfig.Configuration.svg?color=royalblue)](https://www.nuget.org/packages/DotNetConfig.Configuration) [![Downloads](https://img.shields.io/nuget/dt/DotNetConfig.Configuration.svg?color=darkmagenta)](https://www.nuget.org/packages/DotNetConfig.Configuration)\n\n```\nPM\u003e Install-Package DotNetConfig.Configuration\n```\n\n\u003c!-- #extensions --\u003e\nUsage (in this example, also chaining other providers):\n\n```csharp\nvar config = new ConfigurationBuilder()\n    .AddJsonFile(...)\n    .AddEnvironmentVariables()\n    .AddIniFile(...)\n    .AddDotNetConfig();\n```\n\nGiven the following .netconfig: \n\n```gitconfig\n[serve]\n\tport = 8080\n\n[security \"admin\"]\n    timeout = 60\n```\n\nYou can read both values with:\n\n```csharp\nstring port = config[\"serve:port\"];  // == \"8080\";\nstring timeout = config[\"security:admin:timeout\"];  // == \"60\";\n```\n\n\u003c!-- #extensions --\u003e\n\n### System.CommandLine\n\n[![Version](https://img.shields.io/nuget/v/DotNetConfig.CommandLine.svg?color=royalblue)](https://www.nuget.org/packages/DotNetConfig.CommandLine) [![Downloads](https://img.shields.io/nuget/dt/DotNetConfig.CommandLine.svg?color=darkmagenta)](https://www.nuget.org/packages/DotNetConfig.CommandLine)\n\nGiven the explicit goal of making **.netconfig** a first-class citizen among dotnet (global) tools, it offers \nexcelent and seamless integration with [System.CommandLine](https://www.nuget.org/packages/System.CommandLine).\n\nLet's asume you create a CLI app named `package` which manages your local cache of packages (i.e. NuGet). \nYou might have a couple commands, like `download` and `prune`, like so:\n\n```csharp\nvar root = new RootCommand\n{\n  new Command(\"download\")\n  {\n    new Argument\u003cstring\u003e(\"id\")\n  },\n  new Command(\"prune\")\n  {\n    new Argument\u003cstring\u003e(\"id\"),\n    new Option\u003cint\u003e(\"days\")\n  },\n}.WithConfigurableDefaults(\"package\");\n```\n\nThe added `WithConfigurableDefaults` invocation means that now all arguments and options can have \ntheir default values specified in config, such as:\n\n```gitconfig\n[package]\n  id = DotNetConfig\n\n[package \"prune\"]\n  days = 30\n```\n\nNote how the `id` can be specified at the top level too. The integration will automatically promote \nconfigurable values to ancestor sections as long as they have compatible types (both `id` in `download` \nand `prune` commands are defined as `string`).\n\nRunning `package -?` from the command line will now pull the rendered default values from config, so \nyou can see what will actually be used if the command is run with no values:\n\n```\nUsage:\n  package [options] [command]\n\nOptions:\n  --version       Show version information\n  -?, -h, --help  Show help and usage information\n\nCommands:\n  download \u003cid\u003e  [default: DotNetConfig]\n  prune \u003cid\u003e     [default: DotNetConfig]\n```\n\nAnd `package prune -?` would show:\n\n```\nUsage:\n  package [options] prune [\u003cid\u003e]\n\nArguments:\n  \u003cid\u003e  [default: DotNetConfig]\n\nOptions:\n  --days \u003cdays\u003e   [default: 30]\n  -?, -h, --help  Show help and usage information\n```\n\nSince **.netconfig** supports multi-valued variables, it's great for populating default \nvalues for arguments or options that can be specified more than once. By making this \nsimple change to the argument above:\n\n```csharp\n    new Argument\u003cstring[]\u003e(\"id\")\n```\n\nWe can now support a configuration like the following:\n\n```gitconfig\n[package]\n  id = DotNetConfig\n  id = Moq\n  id = ThisAssembly\n```\n\nAnd running the command with no `id` argument will now cause the handler to receive all three. You \ncan also verify that this is the case via `download -?`, for example:\n\n```\nUsage:\n  package [options] download [\u003cid\u003e...]\n\nArguments:\n  \u003cid\u003e  [default: DotNetConfig|Moq|ThisAssembly]\n\nOptions:\n  -?, -h, --help  Show help and usage information\n```\n\nAll the types supported by System.CommandLine for multiple artity arguments and options are \nautomatically populated: arrays, `IEnumerable\u003cT\u003e`, `ICollection\u003cT\u003e`, `IList\u003cT\u003e` and `List\u003cT\u003e`. \n\nFor numbers, the argument/option can be either `long` or `int`. Keep in mind that since numbers in \n**.netconfig** are always `long`, truncation may occur in the latter case.\n\n\n## CLI\n\n[![Version](https://img.shields.io/nuget/v/dotnet-config.svg?color=royalblue)](https://www.nuget.org/packages/dotnet-config) [![Downloads](https://img.shields.io/nuget/dt/dotnet-config.svg?color=darkmagenta)](https://www.nuget.org/packages/dotnet-config)\n\n\u003c!-- #cli --\u003e\nThe command line tool allows you to inspect and modify configuration files used by your dotnet tools. \nInstallation is the same as for any other dotnet tool: \n\n```\n\u003e dotnet tool install -g dotnet-config\n```\n\nThe available options and actions are (for the most part) compatible with the behavior of `git config`.\n\n\u003e When reading and writing from a single file, you can for the most part just use `git config`\n\u003e along with the compatibility option `-f|--file` specifying the file to read/write from.\n\nReading and writing variables don't require any special options. The following lines first \nwrite a variable value and then retrieve its value:\n\n```\n\u003e dotnet config mytool.myvariable myvalue\n\u003e dotnet config mytool.myvariable\nmyvalue\n```\n\nThe value is returned verbatim via the standard output, so you can assign it directly to a \nvariable, for example.\n\nAll current options from running `dotnet config -?` are:\n\n```\nUsage: dotnet config [options]\n\nLocation (uses all locations by default)\n      --global               use global config file\n      --system               use system config file\n      --local                use .netconfig.user file\n  -f, --file                 use given config file (git config compat)\n      --path[=VALUE]         use given config file or directory\n\nAction\n      --get                  get value: name [value-regex]\n      --get-all              get all values: key [value-regex]\n      --get-regexp           get values for regexp: name-regex [value-regex]\n      --add                  add a new variable: name value\n      --unset                remove a variable: name [value-regex]\n      --unset-all            remove all matches: name [value-regex]\n      --set                  set value: name value [value-regex]\n      --set-all              set all matches: name value [value-regex]\n      --rename-section       rename section: old-name new-name\n      --remove-section       remove a section: name\n  -l, --list                 list all\n  -e, --edit                 edit the config file in an editor\n\nOther\n      --name-only            show variable names only\n      --default[=VALUE]      with --get, use default value when missing entry\n      --type[=VALUE]         value is given this type, can be 'boolean', '\n                               datetime' or 'number'\n  -?, -h, --help             Display this help\n```\n\nCommand line parsing is done with [Mono.Options](https://www.nuget.org/packages/mono.options) so \nall the following variants for arguments are supported: `-flag`, `--flag`, `/flag`, `-flag=value`, \n`--flag=value`, `/flag=value`, `-flag:value`, `--flag:value`, `/flag:value`, `-flag value`, \n`--flag value`, `/flag value`.\n\n\u003c!-- #cli --\u003e\n\u003c!-- #content --\u003e\n\u003c!-- include https://github.com/devlooped/sponsors/raw/main/footer.md --\u003e\n# Sponsors \n\n\u003c!-- sponsors.md --\u003e\n[![Clarius Org](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/clarius.png \"Clarius Org\")](https://github.com/clarius)\n[![MFB Technologies, Inc.](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/MFB-Technologies-Inc.png \"MFB Technologies, Inc.\")](https://github.com/MFB-Technologies-Inc)\n[![Torutek](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/torutek-gh.png \"Torutek\")](https://github.com/torutek-gh)\n[![DRIVE.NET, Inc.](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/drivenet.png \"DRIVE.NET, Inc.\")](https://github.com/drivenet)\n[![Keith Pickford](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/Keflon.png \"Keith Pickford\")](https://github.com/Keflon)\n[![Thomas Bolon](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/tbolon.png \"Thomas Bolon\")](https://github.com/tbolon)\n[![Kori Francis](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/kfrancis.png \"Kori Francis\")](https://github.com/kfrancis)\n[![Toni Wenzel](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/twenzel.png \"Toni Wenzel\")](https://github.com/twenzel)\n[![Uno Platform](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/unoplatform.png \"Uno Platform\")](https://github.com/unoplatform)\n[![Dan Siegel](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/dansiegel.png \"Dan Siegel\")](https://github.com/dansiegel)\n[![Reuben Swartz](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/rbnswartz.png \"Reuben Swartz\")](https://github.com/rbnswartz)\n[![Jacob Foshee](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/jfoshee.png \"Jacob Foshee\")](https://github.com/jfoshee)\n[![](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/Mrxx99.png \"\")](https://github.com/Mrxx99)\n[![Eric Johnson](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/eajhnsn1.png \"Eric Johnson\")](https://github.com/eajhnsn1)\n[![Ix Technologies B.V.](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/IxTechnologies.png \"Ix Technologies B.V.\")](https://github.com/IxTechnologies)\n[![David JENNI](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/davidjenni.png \"David JENNI\")](https://github.com/davidjenni)\n[![Jonathan ](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/Jonathan-Hickey.png \"Jonathan \")](https://github.com/Jonathan-Hickey)\n[![Charley Wu](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/akunzai.png \"Charley Wu\")](https://github.com/akunzai)\n[![Jakob Tikjøb Andersen](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/jakobt.png \"Jakob Tikjøb Andersen\")](https://github.com/jakobt)\n[![Tino Hager](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/tinohager.png \"Tino Hager\")](https://github.com/tinohager)\n[![Ken Bonny](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/KenBonny.png \"Ken Bonny\")](https://github.com/KenBonny)\n[![Simon Cropp](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/SimonCropp.png \"Simon Cropp\")](https://github.com/SimonCropp)\n[![agileworks-eu](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/agileworks-eu.png \"agileworks-eu\")](https://github.com/agileworks-eu)\n[![sorahex](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/sorahex.png \"sorahex\")](https://github.com/sorahex)\n[![Zheyu Shen](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/arsdragonfly.png \"Zheyu Shen\")](https://github.com/arsdragonfly)\n[![Vezel](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/vezel-dev.png \"Vezel\")](https://github.com/vezel-dev)\n[![ChilliCream](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/ChilliCream.png \"ChilliCream\")](https://github.com/ChilliCream)\n[![4OTC](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/4OTC.png \"4OTC\")](https://github.com/4OTC)\n[![Vincent Limo](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/v-limo.png \"Vincent Limo\")](https://github.com/v-limo)\n[![Jordan S. Jones](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/jordansjones.png \"Jordan S. Jones\")](https://github.com/jordansjones)\n[![domischell](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/DominicSchell.png \"domischell\")](https://github.com/DominicSchell)\n[![Joseph Kingry](https://raw.githubusercontent.com/devlooped/sponsors/main/.github/avatars/jkingry.png \"Joseph Kingry\")](https://github.com/jkingry)\n\n\n\u003c!-- sponsors.md --\u003e\n\n[![Sponsor this project](https://raw.githubusercontent.com/devlooped/sponsors/main/sponsor.png \"Sponsor this project\")](https://github.com/sponsors/devlooped)\n\u0026nbsp;\n\n[Learn more about GitHub Sponsors](https://github.com/sponsors)\n\n\u003c!-- https://github.com/devlooped/sponsors/raw/main/footer.md --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdotnetconfig%2Fdotnet-config","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdotnetconfig%2Fdotnet-config","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdotnetconfig%2Fdotnet-config/lists"}