{"id":13343346,"url":"https://github.com/archipaorg/icl","last_synced_at":"2025-03-12T04:33:21.684Z","repository":{"id":57098551,"uuid":"104461755","full_name":"archipaorg/icl","owner":"archipaorg","description":"A configuration language written for the modern apps","archived":false,"fork":false,"pushed_at":"2017-09-27T15:08:37.000Z","size":161,"stargazers_count":10,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-06T09:28:13.363Z","etag":null,"topics":["configuration-language","json","yaml"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/archipaorg.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}},"created_at":"2017-09-22T10:18:45.000Z","updated_at":"2024-10-06T17:24:36.000Z","dependencies_parsed_at":"2022-08-20T16:51:14.312Z","dependency_job_id":null,"html_url":"https://github.com/archipaorg/icl","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/archipaorg%2Ficl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/archipaorg%2Ficl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/archipaorg%2Ficl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/archipaorg%2Ficl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/archipaorg","download_url":"https://codeload.github.com/archipaorg/icl/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243158974,"owners_count":20245668,"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-language","json","yaml"],"created_at":"2024-07-29T19:31:08.562Z","updated_at":"2025-03-12T04:33:21.409Z","avatar_url":"https://github.com/archipaorg.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":" \n# ICL (Ichiro Configuration Language)\n[![Build Status](https://travis-ci.org/archipaorg/icl.svg?branch=master)](https://travis-ci.org/archipaorg/icl)\n[![License: MPL 2.0](https://img.shields.io/badge/License-MPL%202.0-brightgreen.svg)](https://opensource.org/licenses/MPL-2.0)\n[![npm](https://img.shields.io/npm/v/npm.svg)]()\n\nICL is a configuration language, that aims to provide a concise and elegant way to describe your configurations files. Moreover ICL relies on some powerfull concepts taken from the OO world (such as inheritance, class, mixins...)  without falling into the trap of becoming a programming language.\n\n## Key features:\n\n+ Simplicity \u0026 Readability : thanks to a simple specification and a declarative syntax that is easy to understand and grasp, everyone can start to use and master ICL very quickly.\n+ Non turing-complete language : common sens tells us that configuration language should not be programmable and stay simple, otherwise our configurations files turns to a spaghetti nightmare.\n+ Full JSON / YAML compatibility : You can think of ICL as JSON / YAML cousin, everything that you can write in JSON or YAML can be expressed in ICL.\n+ Powerfull Tooling : Even the best language in the world without tooling is almost useless in our time, this is why we developped a nice vs plugin to support your icl devs.\n\n## Syntax : \n\n### Overview\n\nBefore diving deeper into ICL syntax here is a preview of what it looks like to write in ICL and it's equivalent in JSON on the right side\n\n![hello world](https://s26.postimg.org/4jywag28p/Screen_Shot_2017-09-18_at_12.27.24.png)\n\nAs you can see, an ICL document is composed of a set of settings block, the latter has a category (in our example, it's \"app\"), followed by at least one property name and of course it's value (in our example it's \"hello-world\")\n\nAs the compiler reads your ICL documents and settings blocks one by one, it merges/interpolates and builds your final JSON/YAML document. Therefore as we will see later, you can split your declarations into multiple files which will increase the reutilisability and readability of your settings blocks.\n\n### Comment\nA hash symbol or a double forward slash marks the rest of the line as a comment.\n\n\t# this is a full-line comment\n\t// this is also a full line comment\n\nMulti-line comment begins with /* and ends with */.\n\n\t/* this is a\n\tmultiline comment */\n\n### Basic structure\nThe primary building block in ICL is a settings block, it's a fundamental unit in ICL grammar, a settings block will hold a group of key/value pairs or even another sub settings block.\nYou can declare a settings block simply by specifiying a category (the category notion here is equivalent to a section in INI terminolgy), then you have to specify one or more properties and finally give a value to this block.\n\ne.g.\n\t\n\tapp \"frontend\" \"instance_1\" {\n\t        port = 3306\n\t}\n\n\nThis is equivalent to the following JSON structure\n\n\t{\n\t    \"app\": {\n\t        \"frontend\": {\n\t            \"instance_1\": {\n\t                \"port\": 3306\n\t            }\n\t        }\n\t    }\n\t}\n\nHowever, if your settings block doesn't have a category, you can only put an underscore `_`\n\t\nIn our example, if i want my frontend to be \"uncategorized\" i simply put an underscore `_` instead of the category name `app`\n\ne.g.\n\n\t  _ \"frontend\" \"instance_1\" {\n\t   \t\tport = 3306\n\t   }\n\nThis is equivalent to the following JSON structure \n\t\n\t{\n\t\t\"frontend\": {\n\t\t\t\"instance_1\": {\n\t    \t\t\t\"port\": 3306\n\t \t\t}\n\t\t}\n\t}\n\n### Library Settings Block\nA library settings block is a block that will not be included in the generated (JSON/YAML) output, as you will see later those kind of blocks can be used as libraries.\nIn order to declare a settings block as a library you just have to prepend it's category name with `::`\n\ne.g.\n\n\t::image \"mysql\" {\n\t   \turl = \"mysql:5.6\",\n\t\tport = 3306\n\t}\n\nThe generated output will be an empty JSON in thise case.\n\n### Inheritance \nIn ICL every settings block can be used as a prototype for another settings block, in fact an ICL settings block can inherit properties from one or even several settings blocks enabling us to construct a settings block from the values of multiple ones.  \n\n\u003e If a setting block inherit from several other settings blocks that define the same properties, they will be overwritten based on the inheritance declaration order (the latest one will win obviously)\n\ne.g.\n\n\t::image \"settings\" {\n\t\tmemory = 8096\n\t}\n\t\n\t::image \"mysql\" {\n\t\turl = \"mysql:5.6\",\n\t\tport = 3306\n\t}\n\t\n\tdb \"instance_1\" from image.mysql, image.settings {}\n\tdb \"instance_2\" from image.mysql, image.settings {}\n\nThis is equivalent to the following JSON structure\n\ne.g. \n\n\t{\n\t    \"db\": {\n\t        \"instance_1\": {\n\t            \"memory\": 8096,\n\t            \"port\": 3306,\n\t            \"url\": \"mysql:5.6\"\n\t        },\n\t        \"instance_2\": {\n\t            \"memory\": 8096,\n\t            \"port\": 3306,\n\t            \"url\": \"mysql:5.6\"\n\t        }\n\t    }\n\t}\n\n\n### Aliases\nEvery settings block can be aliased, by giving it an alias and declare it as a library settings block you are definining a type that can be reused later. Let's see again the previous example but this time we are going to leverage the use of the alias feature instead of explicitly specifying the inheritance.\n\ne.g.\n\n\t::image \"mysql\" as MySQL {\n\t\turl = \"mysql:5.6\",\n\t\tport = 3306\n\t}\n\t\t\n\tMySQL \"db\" \"instance_1\" {}\t\n\tMySQL \"db\" \"instance_2\" {}\n\t\nThis generates the following JSON \n\n\t {   \n\t \t\"db\": {\n\t        \"instance_1\": {\n\t            \"port\": 3306,\n\t            \"url\": \"mysql:5.6\"\n\t        },\n\t        \"instance_2\": {\n\t            \"port\": 3306,\n\t            \"url\": \"mysql:5.6\"\n\t        }\n\t    }\n\t}\n\n### Mixins \nIn order to make a settings block more reusable you can define some arguments, and then call this block later on with the appropriate values. That's what mixins are meant for.\n\ne.g.\n\n\t::image \"basic\" @name, @version {\n\t    url = \"@name:@version\"\n\t}\n\nThe call of mixins is implemented in ICL by the keyword `apply` to which we pass the pairs parameter-value\t\n\t\n\tapp \"mysql\" apply image.basic @name=\"mysql\", @version=5.6\n\nThe latter will generates this equivalent JSON output :\n\n\t{\n\t    \"app\": {\n\t        \"mysql\": {\n\t            \"url\": \"mysql:5.6\"\n\t        }\n\t    }\n\t}\n\n### Assignements\n\nThe assignment operator is to assign a value to a particular property, it's like a mixin parameter but a one that will be assigned to a particular property, Its preceded by `@@` rather then `@`.\n\ne.g.\n\n\t::image \"mysql\" {\n\t    url = \"mysql:5.6\",\n\t    port = 3306\n\t}\n\t\t\t\n\tmysql \"instance_1\" apply image.mysql @@port=3307 \n\nThis will generates the following JSON \n\n\t{\n\t    \"mysql\": {\n\t        \"instance_1\": {\n\t            \"port\": 3307,\n\t            \"url\": \"mysql:5.6\"\n\t        }\n\t    }\n\t}\n\n### Imports\nSometimes you want to split your icl declarations accross many files for maintainability, that's where imports comes into play, in ICL you can import as many icl files as you want and at any point in the icl file.(not necessarly at the top of the file)\n\ne.g.\n\n./lib.icl file\n\n\t::image \"mysql\" as MySQL {\n\t\turl = \"mysql:5.6\",\n\t\tport = 3306\n\t}\n\n./app.icl file\n\n\ttake lib\n \tMySQL \"db\" \"instance_1\" {}\t\n\tMySQL \"db\" \"instance_2\" {}\n\t\nThe generated output in JSON will be \n\n\t {   \n\t \t\"db\": {\n\t        \"instance_1\": {\n\t            \"port\": 3306,\n\t            \"url\": \"mysql:5.6\"\n\t        },\n\t        \"instance_2\": {\n\t            \"port\": 3306,\n\t            \"url\": \"mysql:5.6\"\n\t        }\n\t    }\n\t}\n\n\nWhen the compiler reads the `take` line, it copies the contents of file1,file2...at that point into the current file.\n  \n    \n### Data types     \n    \n#### Number\n\nThe number type is used for any numeric type, either integers or floating point numbers, positive numbers may be prefixed with a plus sign. Negative numbers are prefixed with a minus sign.\n\ne.g.          \n\t\n\tcloud \"digiteal_ocean\" \"transfer\" 5 \n        \n     /* Here the setting block cotain \n        cloud as category and digitealocean as property \n        and transfer as sub_property and 5 as integer value */\n        \n\t cloud \"digiteal_ocean\" \"droplet\" {\n            port = 3306,\n            price = +4.5\n       }\n       \n#### Boolean\nIt includes true or false values.\n\ne.g: \n\t    \n\tcloud \"digiteal_ocean\" \"fw\" true \n\t                                \n\n#### String\n\nStrings can be double quoted `\"`or single quoted `'` and can contain any text. If your string contains a double quote or a single quote you can escape them \\\" or \\' \n\ne.g.: \n\n\tcloud \"digital_ocean\" {\n\t\tname = 'this is just mysql digital ocean\\'s droplet'\n\t} \n\nor \n\t\n\tcloud \"digital_ocean\" {\n\t\tname = \"this is just mysql digital ocean's droplet\"\n\t} \n\nNote the 'quotes' around the value. When the value is a text string, \n\nAll strings are multiline by default, no need to do any extra stuff:\n\ne.g.\n\n\tapp \"hello-world\" {\n\t            name = \"this is \n\t\t\ta multiline \n\t            string\",\n\t            price = +4.5\n\t }\n\nThis generates the following JSON : \n\n\t{\n\t    \"app\": {\n\t        \t\"hello-world\": {\n\t            \t\t\"name\": \"this is \\na multiline \\nstring\",\n\t            \t\t\"price\": 4.5\n\t        \t}\n\t    }\n\t}\n\n#### Raw Data\n\nICL can handle the insertion of raw data such as encoded image files. this can be achieved in ICL through [heredoc](https://en.wikipedia.org/wiki/Here_document) \n\ne.g.: \n   \n     app \"hello-world\" {\n            icon = \u003c\u003c\u003cEOF R0lGODlhPQBEAPeoAJosMAwOAwHVYZz595kzAPs7P+goOXMv8+fhwv739f+8PD98fH8mJl+fn9ZWb8PzWlwv6wWGbImAPgTEMImIN9gUFCEmgDALULDN8PAD6atYdCTX9gUNKlj8wZAKUsAOzZz+UMAOsJAPZ2ccMDA8PD95eX5NWvsJCOVNQPtfX8zM8+QePLl38MGBr8JCP+zs9myn8GBqwpAPGxgwJCPny78lzYLgjAJ8vAP9fX+MjMUcAN8zM9wcM8ZGcATEL+QePdZWf\n            29ucP9cmJu9MTDImIN+r7+vz8P8VNQGNugV8AAF9fX8swMNg\n            TAFlDOICAgPNSUnNWSMQ5MBAQEJE3Q\n            EOF\n\t}\n \n#### Null\nNull values can be declared with the `null` keyword\n\ne.g.\n\n\t app \"settings\"{\n\t \tmax_count = null\n\t }\n\n\n#### List       \n\nLists are square brackets with values inside, whitespace is ignored. Elements are separated by commas. Lists can contain primitives, other Lists, maps and raw data.\n\ne.g.  \n           \n\tcloud \"digitealocean\" \"transfer\" option [  \n                    1, // integer\n                    3.5, // float\n                    \"simple string\", // another string\n                    [1,2,3, [1,2,3]], // list of list of list\n                    [\"foo\", \"bar\", 3.14, [1, 5], {\"foo\", \"bar\",5...}...], \n                    {key = \"foo\",\"bar\"... } // map\n                      ]\n\n#### Table \nTable are 2 dimensional array and declared through the `table` keyword\n\n\tapp \"hello-world\" \"dns\" table \"localhost\" \t= \"127.0.0.1\",\n\t\t\t\t\t\t\"hello-world.com\"   = \"221.192.199.49\"\n\n#### Map\n\nMaps are a collections of key-value pairs (delimited by `,`). maps are enclosed in curly braces `{` and `}`\n\ne.g.    \n\n    map \"elements\" {\n    \t\tproperty1 = \"value1\",\n    \t\tproperty2 = \"value2\"\n    }\n\nThe value of each property can be of any type (number, boolean, map, list, null...)\n \t\t\t            \n## Get Involved\n\nWe love contributions! There's lots to do on ICL and vscode extension, so why not chat with us about what you're interested in doing? Please join the #Ichiro channel on our Slack channel and let us know about your plans.\n\nDocumentation, bug reports, pull requests, and all other contributions are welcome!\n\nTo suggest a feature or report a bug: https://github.com/archipaorg/icl/issues\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farchipaorg%2Ficl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farchipaorg%2Ficl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farchipaorg%2Ficl/lists"}