{"id":18633749,"url":"https://github.com/allisterb/alpheus","last_synced_at":"2025-07-11T03:02:16.964Z","repository":{"id":92716201,"uuid":"65250870","full_name":"allisterb/Alpheus","owner":"allisterb","description":"Cross-platform configuration file parser","archived":false,"fork":false,"pushed_at":"2018-02-04T22:06:18.000Z","size":329,"stargazers_count":22,"open_issues_count":1,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-06-17T11:07:34.754Z","etag":null,"topics":["configuration-management","dotnet","parser"],"latest_commit_sha":null,"homepage":"","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/allisterb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2016-08-09T01:02:21.000Z","updated_at":"2022-07-31T05:17:48.000Z","dependencies_parsed_at":"2023-03-21T03:32:57.232Z","dependency_job_id":null,"html_url":"https://github.com/allisterb/Alpheus","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/allisterb/Alpheus","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allisterb%2FAlpheus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allisterb%2FAlpheus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allisterb%2FAlpheus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allisterb%2FAlpheus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/allisterb","download_url":"https://codeload.github.com/allisterb/Alpheus/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allisterb%2FAlpheus/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264719224,"owners_count":23653540,"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":["configuration-management","dotnet","parser"],"created_at":"2024-11-07T05:16:09.192Z","updated_at":"2025-07-11T03:02:16.938Z","avatar_url":"https://github.com/allisterb.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Alpheus: Cross-platform configuration file parser\nGet the latest release for .NET Standard from the [releases](https://github.com/allisterb/Alpheus/releases) page or through [NuGet](https://www.nuget.org/packages/Alpheus.Core/). Packages built for .NET Framework 4.5+ are also [available](https://www.nuget.org/packages/) or can be built from source.\n\n![Screenshot](https://1qirkq.dm2301.livefilestore.com/y4mBoMY8wR3dfFOclfZKWnIZtrYC68PNYM3adTZCN9WUtZEzcnZhPAqvXseSkBsEnuB3vAvZN45fDx7MbNoAuqhFEDTu73qwqH2OZxtp-C-j7XYGr1MhjXdLCfGGDhipzTIwmgX7P3rB1huY-u8hl1JMQxWjf4XJzUyga2eN8b9-0cSO6YYufKhzQ6wrgKvxXTEsx2EDQ8id8S_sZ8D1BuDog?width=1121\u0026height=799\u0026cropmode=none)\n\n## About\nAlpheus is a parser and query tool for system and server configuration files. Alpheus parses and transforms configuration files into an XML representation which can then be queried using XPATH. E.g. from the following fragment from a MySQL `my.cnf` configuration file:\n\n````\n#\n# * InnoDB\n#\n# InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/.\n# Read the manual for more InnoDB related options. There are many!\ninnodb_additional_mem_pool_size=256M\ninnodb_buffer_pool_size=20GB\n# number of CPU cores dedicated to the MySQL InnoDB backend \ninnodb_buffer_pool_instances = 4\ninnodb_log_buffer_size=256M\ninnodb_log_file_size=1G\nbulk_insert_buffer_size=256M\ninnodb_flush_log_at_trx_commit=2\ninnodb_flush_method=O_DIRECT\ninnodb_doublewrite = 0\ninnodb_file_per_table = 1\ninnodb_file_format = barracuda\n\n[mysqldump]\nquick\nquote-names\nmax_allowed_packet\t= 16M\n\n[mysql]\n#no-auto-rehash\t# faster start of mysql but no tab completition\n\n[isamchk]\nkey_buffer\t\t= 16M\n\n!includedir /etc/mysql/conf.d/\n````\n\nAlpheus transforms the sections and directives in the configuration file into the following XML:\n````                                                                \n    ...\n    \u003cinnodb_log_buffer_size Position=\"4953\" Column=\"1\" Line=\"148\" Length=\"22\" File=\"my.cnf\"\u003e         \n      \u003cValue Position=\"4976\" Column=\"24\" Line=\"148\" Length=\"4\"\u003e256M\u003c/Value\u003e                          \n    \u003c/innodb_log_buffer_size\u003e                                                                        \n    \u003cinnodb_log_file_size Position=\"4982\" Column=\"1\" Line=\"149\" Length=\"20\" File=\"my.cnf\"\u003e           \n      \u003cValue Position=\"5003\" Column=\"22\" Line=\"149\" Length=\"2\"\u003e1G\u003c/Value\u003e                            \n    \u003c/innodb_log_file_size\u003e                                                                          \n    \u003cbulk_insert_buffer_size Position=\"5007\" Column=\"1\" Line=\"150\" Length=\"23\" File=\"my.cnf\"\u003e        \n      \u003cValue Position=\"5031\" Column=\"25\" Line=\"150\" Length=\"4\"\u003e256M\u003c/Value\u003e                          \n    \u003c/bulk_insert_buffer_size\u003e                                                                       \n    \u003cinnodb_flush_log_at_trx_commit Position=\"5037\" Column=\"1\" Line=\"151\" Length=\"30\" File=\"my.cnf\"\u003e \n      \u003cValue Position=\"5068\" Column=\"32\" Line=\"151\" Length=\"1\"\u003e2\u003c/Value\u003e                             \n    \u003c/innodb_flush_log_at_trx_commit\u003e                                                                \n    \u003cinnodb_flush_method Position=\"5071\" Column=\"1\" Line=\"152\" Length=\"19\" File=\"my.cnf\"\u003e            \n      \u003cValue Position=\"5091\" Column=\"21\" Line=\"152\" Length=\"8\"\u003eO_DIRECT\u003c/Value\u003e                      \n    \u003c/innodb_flush_method\u003e                                                                           \n    \u003cinnodb_doublewrite Position=\"5101\" Column=\"1\" Line=\"153\" Length=\"18\" File=\"my.cnf\"\u003e             \n      \u003cValue Position=\"5122\" Column=\"22\" Line=\"153\" Length=\"1\"\u003e0\u003c/Value\u003e                             \n    \u003c/innodb_doublewrite\u003e                                                                            \n    \u003cinnodb_file_per_table Position=\"5125\" Column=\"1\" Line=\"154\" Length=\"21\" File=\"my.cnf\"\u003e          \n      \u003cValue Position=\"5149\" Column=\"25\" Line=\"154\" Length=\"1\"\u003e1\u003c/Value\u003e                             \n    \u003c/innodb_file_per_table\u003e                                                                         \n    \u003cinnodb_file_format Position=\"5152\" Column=\"1\" Line=\"155\" Length=\"18\" File=\"my.cnf\"\u003e             \n      \u003cValue Position=\"5173\" Column=\"22\" Line=\"155\" Length=\"9\"\u003ebarracuda\u003c/Value\u003e                     \n    \u003c/innodb_file_format\u003e                                                                            \n  \u003c/mysqld\u003e                                                                                          \n  \u003cmysqldump File=\"my.cnf\"\u003e                                                                          \n    \u003cquick Position=\"5494\" Column=\"1\" Line=\"172\" Length=\"5\" File=\"my.cnf\"\u003e                           \n      \u003cValue Position=\"5494\" Column=\"1\" Line=\"172\" Length=\"4\"\u003etrue\u003c/Value\u003e                           \n    \u003c/quick\u003e                                                                                         \n    \u003cquote-names Position=\"5501\" Column=\"1\" Line=\"173\" Length=\"11\" File=\"my.cnf\"\u003e                    \n      \u003cValue Position=\"5501\" Column=\"1\" Line=\"173\" Length=\"4\"\u003etrue\u003c/Value\u003e                           \n    \u003c/quote-names\u003e                                                                                   \n    \u003cmax_allowed_packet Position=\"5514\" Column=\"1\" Line=\"174\" Length=\"18\" File=\"my.cnf\"\u003e             \n      \u003cValue Position=\"5535\" Column=\"22\" Line=\"174\" Length=\"3\"\u003e16M\u003c/Value\u003e                           \n    \u003c/max_allowed_packet\u003e                                                                            \n  \u003c/mysqldump\u003e \n  \u003cmysql File=\"my.cnf\" /\u003e\n  \u003cisamchk File=\"my.cnf\"\u003e\n    \u003ckey_buffer Position=\"5629\" Column=\"1\" Line=\"180\" Length=\"10\" File=\"my.cnf\"\u003e\n      \u003cValue Position=\"5643\" Column=\"15\" Line=\"180\" Length=\"3\"\u003e16M\u003c/Value\u003e\n    \u003c/key_buffer\u003e\n    \u003cincludedir Position=\"5800\" Column=\"2\" Line=\"186\" Length=\"10\" File=\"my.cnf\"\u003e\n      \u003cValue Position=\"5811\" Column=\"13\" Line=\"186\" Length=\"18\"\u003e/etc/mysql/conf.d/\u003c/Value\u003e\n    \u003c/includedir\u003e\n  \u003c/isamchk\u003e\n\u003c/MySQL\u003e\n  ````\nYou can then query the XML representation using the XPATH query language e.g. the following screenshot shows a query of the `Port` directive in the `[mysqld]` section of the `my.cnf` file:\n\n![Query screenshot](https://1qik4g.dm2301.livefilestore.com/y4mCaV-1xfjcayXYIl7SrtBrrrJr6vmdO366CkHgXtNdi6cMdQWiHIrqiZ0Gw9KT1JbhPvLC1b-GFkWmwXWFSzWf4EvcHK5iubR-JqSOMa-RA1n1FRozOxEjV0BvszNNSXHUk55KqNCKVRem4_I7cnQ8quFHUMbGwpdmTvlNzogrSsB6R9VZxWItPxCZxYoteUfc9ki2YoiPR04b42YaiEFsA?width=1106\u0026height=796\u0026cropmode=none)\n\nAlpheus is similar in goals to the [Augeas](http://augeas.net/) project but with quite different execution:\n\n* Augeus is written for Linux with only [nascent Windows support](https://github.com/hercules-team/augeas/issues/476) that requires a compatibilty layer like Cygwin. Alpheus runs on any platform with .NET support: .NET Framework, Mono, or .NET Core. \n\n* Augeas is written in C and uses the [Boomerang](https://alliance.seas.upenn.edu/~harmony/) language which is a subset of ML for writing parsers. Alpheus is written in C# and uses the [Sprache](https://github.com/sprache/Sprache) monadic parser combinator library. Parser combinators are a good match for OOP languages with functional bits like C#. Sprache and C# allow you to use functional idioms while incrementally building and testing parsers and reusing existing grammar pieces, e.g. the following code is a part of the Alpheus MySQL grammar:\n````\n            public static Parser\u003cAString\u003e KeyName\n            {\n                get\n                {\n                    return AStringFrom(AlphaNumericIdentifierChar.Or(Underscore).Or(Dash));\n                }\n            }\n\n            public static Parser\u003cAString\u003e KeyValue\n            {\n                get\n                {\n                    return AnyCharExcept(\"'\\\"\\r\\n\");\n                }\n              \n            }\n\n            public static Parser\u003cAString\u003e QuotedKeyValue\n            {\n                get\n                {\n                    return DoubleQuoted(Optional(KeyValue)).Or(SingleQuoted(Optional(KeyValue)));\n                }\n\n            }\n\n            public static Parser\u003cAString\u003e SectionName\n            {\n                get\n                {\n                    return\n                        from w1 in OptionalMixedWhiteSpace\n                        from ob in OpenSquareBracket\n                        from sn in SectionNameAString\n                        from cb in ClosedSquareBracket\n                        select sn;\n                }\n            }\n````\nFunctions as first-class objects together with LINQ expressions are used to construct the parser grammar in C# while reusing and combining existing parser bits.\n\n* Augeas reads local file-system files only. Alpheus abstracts the I/O operations required for reading files into an interface and can read files from any class that implements the interface. For instance the [DevAudit](https://github.com/OSSIndex/DevAudit) project implements I/O environments for SSH, GitHub, Docker containers et.al and [uses Alpheus](https://github.com/OSSIndex/DevAudit/blob/dd0efc6b459711115450ae7decdf1162b882fe06/DevAudit.AuditLibrary/Servers/PostgreSQLServer.cs#L131) to directly parse and query configuration files from remote environments.\n\n* Alpheus understands the semantics of configuration files in addition to the syntax. For instance Alpheus can recognize MySQL `include` and `includedir` directives and inserts the parsed included files into the XML representation. E.g. from the following MySQL configuration:\n````\n[mysqlhotcopy]\ninteractive-timeout\n\n\n!includedir mysql.conf.d\n````\nif the `mysql.conf.d` directory has a file called `my.2.cnf` then the following XML will be produced:\n````\n\u003cmysqlhotcopy File=\"my-large.cnf\"\u003e                                                                \n  \u003cinteractive-timeout Position=\"2591\" Column=\"1\" Line=\"88\" Length=\"19\" File=\"my-large.cnf\"\u003e      \n    \u003cValue Position=\"2591\" Column=\"1\" Line=\"88\" Length=\"4\"\u003etrue\u003c/Value\u003e                           \n  \u003c/interactive-timeout\u003e                                                                          \n  \u003cincludedir Position=\"2617\" Column=\"2\" Line=\"91\" Length=\"10\" File=\"my-large.cnf\"\u003e               \n    \u003cValue Position=\"2628\" Column=\"13\" Line=\"91\" Length=\"12\"\u003emysql.conf.d\u003c/Value\u003e                 \n  \u003c/includedir\u003e                                                                                   \n\u003c/mysqlhotcopy\u003e                                                                                   \n\u003cclient File=\"my.2.cnf\"\u003e                                                                          \n  \u003cport Position=\"737\" Column=\"1\" Line=\"22\" Length=\"4\" File=\"my.2.cnf\"\u003e                           \n    \u003cValue Position=\"745\" Column=\"9\" Line=\"22\" Length=\"4\"\u003e3306\u003c/Value\u003e                            \n  \u003c/port\u003e                                                                                         \n  \u003csocket Position=\"751\" Column=\"1\" Line=\"23\" Length=\"6\" File=\"my.2.cnf\"\u003e                         \n    \u003cValue Position=\"761\" Column=\"11\" Line=\"23\" Length=\"27\"\u003e/var/run/mysqld/mysqld.sock\u003c/Value\u003e   \n  \u003c/socket\u003e                                                                                       \n\u003c/client\u003e                                                                                         \n\u003cmysqld_safe File=\"my.2.cnf\"\u003e                                                                     \n  \u003csocket Position=\"807\" Column=\"1\" Line=\"26\" Length=\"6\" File=\"my.2.cnf\"\u003e                         \n    \u003cValue Position=\"817\" Column=\"11\" Line=\"26\" Length=\"27\"\u003e/var/run/mysqld/mysqld.sock\u003c/Value\u003e   \n  \u003c/socket\u003e                                                                                       \n  \u003cnice Position=\"846\" Column=\"1\" Line=\"27\" Length=\"4\" File=\"my.2.cnf\"\u003e                           \n    \u003cValue Position=\"854\" Column=\"9\" Line=\"27\" Length=\"1\"\u003e0\u003c/Value\u003e                               \n  \u003c/nice\u003e                                                                                         \n\u003c/mysqld_safe\u003e                                                                                    \n````\n\n## Supported formats\nAlpheus can parse and query configuration files for the following servers and applications:\n* OpenSSH (sshd_config)\n* MySQL (my.cnf)\n* PostgreSQL (postgresql.conf)\n* Nginx (nginx.conf)\n* Apache Httpd (httpd.conf)\n* Docker (Dockerfile)\n* .NET and ASP.NET App.config and Web.Config files\n\n## Usage\n### Command Line Interface\nDownload and unzip the release archive. Type `al -v` and `al -h` (`./al -v` or `./al -h` on Linux) to see the version information and help with using the CLI.\n\n### Library\nInstall the [NuGet](https://www.nuget.org/packages/Alpheus.Core/) package into your application. You can read and parse a file like this:\n`MySQL mysql = new MySQL(\"path\\to\\local\\file\");` See the Alpheus CLI source code and tests for examples on how to use the library.\n\n## Building\nClone the Github repository on to your computer. You can build for .NET Framework with the `build-netfx` script on Windows or `./build-netcfx.sh` on Linux. You can also build for .NET Standard/.NET Core with `build-netcore` on Windows or `./build-netcore.sh` on Linux.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fallisterb%2Falpheus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fallisterb%2Falpheus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fallisterb%2Falpheus/lists"}