diff --git a/packages/rang/.clang-format b/packages/rang/.clang-format
new file mode 100644
index 0000000000000000000000000000000000000000..b3b621de98ce9449338841a14607347219dcfdf6
--- /dev/null
+++ b/packages/rang/.clang-format
@@ -0,0 +1,57 @@
+---
+Language:        Cpp
+AccessModifierOffset: -4
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: true
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlinesLeft: false
+AlignOperands:   false
+AlignTrailingComments: false
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: true
+AllowShortFunctionsOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: true
+AllowShortLoopsOnASingleLine: true
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: true
+BinPackArguments: true
+BinPackParameters: true
+BreakBeforeBinaryOperators: All
+BreakBeforeBraces: WebKit
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+ColumnLimit:     80
+ConstructorInitializerAllOnOneLineOrOnePerLine: true
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 2
+Cpp11BracedListStyle: false
+DerivePointerAlignment: false
+DisableFormat:   false
+ExperimentalAutoDetectBinPacking: false
+ForEachMacros:   [ foreach, Q_FOREACH, BOOST_FOREACH ]
+IndentCaseLabels: true
+IndentWidth:     4
+IndentWrappedFunctionNames: false
+KeepEmptyLinesAtTheStartOfBlocks: true
+MaxEmptyLinesToKeep: 2
+NamespaceIndentation: Inner
+PointerAlignment: Right
+ReflowComments:  true
+SortIncludes:    false
+SpaceAfterCStyleCast: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 2
+SpacesInAngles:  false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard:        Cpp11
+TabWidth:        4
+UseTab:          Never
+...
diff --git a/packages/rang/.editorconfig b/packages/rang/.editorconfig
new file mode 100644
index 0000000000000000000000000000000000000000..08f403de32da04391e130e8c769d7f0fae06341a
--- /dev/null
+++ b/packages/rang/.editorconfig
@@ -0,0 +1,19 @@
+# editorconfig.org
+root = true
+
+[*]
+indent_style = space
+indent_size = 4
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.{html,ejs,css,sass,scss,js,yml}]
+indent_size = 2
+
+[*.md]
+trim_trailing_whitespace = false
+
+[{package.json,.travis.yml}]
+indent_size = 2
diff --git a/packages/rang/.gitignore b/packages/rang/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..123821a2e7731ba649e34335829c92aa17951c8f
--- /dev/null
+++ b/packages/rang/.gitignore
@@ -0,0 +1,31 @@
+# Compiled Object files
+*.slo
+*.lo
+*.o
+*.obj
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Compiled Dynamic libraries
+*.so
+*.dylib
+*.dll
+
+# Fortran module files
+*.mod
+
+# Compiled Static libraries
+*.lai
+*.la
+*.a
+*.lib
+
+# Executables
+*.exe
+*.out
+*.app
+
+build/
+.vscode/
diff --git a/packages/rang/.gitrepo b/packages/rang/.gitrepo
new file mode 100644
index 0000000000000000000000000000000000000000..78ea2a909e6bbd9578dfe87fa05f95ec17de8672
--- /dev/null
+++ b/packages/rang/.gitrepo
@@ -0,0 +1,11 @@
+; DO NOT EDIT (unless you know what you are doing)
+;
+; This subdirectory is a git "subrepo", and this file is maintained by the
+; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
+;
+[subrepo]
+	remote = git@github.com:agauniyal/rang.git
+	branch = master
+	commit = 49505595c6941ad58788ade0ecdff26aeb5b7a9a
+	parent = 3851043c52834dd919a64939d3073c926b0e3659
+	cmdver = 0.3.1
diff --git a/packages/rang/.travis.yml b/packages/rang/.travis.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c85aa7957a0db8a456310c9d3e13b92156835a89
--- /dev/null
+++ b/packages/rang/.travis.yml
@@ -0,0 +1,154 @@
+dist: trusty
+sudo: false
+group: travis_latest
+language: c++
+
+env:
+  global:
+  - COMPILER=g++
+
+addons:
+  apt:
+    sources: &apt_sources
+      - ubuntu-toolchain-r-test
+      - llvm-toolchain-precise-3.5
+      - llvm-toolchain-precise-3.6
+      - llvm-toolchain-precise-3.7
+      - llvm-toolchain-precise-3.8
+      - llvm-toolchain-trusty-3.9
+      - llvm-toolchain-trusty-4.0
+      - llvm-toolchain-trusty-5.0
+
+compiler: clang
+os: linux
+
+matrix:
+  fast_finish: true
+  include:
+    - env: COMPILER=g++-5
+      compiler: gcc
+      addons: &gcc5
+        apt:
+          packages: ["g++-5", "python3-pip", "lcov"]
+          sources: *apt_sources
+
+    - env: COMPILER=g++-6
+      compiler: gcc
+      addons: &gcc6
+        apt:
+          packages: ["g++-6", "python3-pip", "lcov"]
+          sources: *apt_sources
+
+    - env: COMPILER=g++-7
+      compiler: gcc
+      addons: &gcc7
+        apt:
+          packages: ["g++-7", "python3-pip", "lcov"]
+          sources: *apt_sources
+
+    - env: COMPILER=clang++-3.5
+      compiler: clang
+      addons: &clang35
+        apt:
+          packages: ["clang-3.5", "g++-7", "python3-pip", "lcov"]
+          sources: *apt_sources
+
+    - env: COMPILER=clang++-3.6
+      compiler: clang
+      addons: &clang36
+        apt:
+          packages: ["clang-3.6", "g++-7", "python3-pip", "lcov"]
+          sources: *apt_sources
+
+    - env: COMPILER=clang++-3.7
+      compiler: clang
+      addons: &clang37
+        apt:
+          packages: ["clang-3.7", "g++-7", "python3-pip", "lcov"]
+          sources: *apt_sources
+
+    - env: COMPILER=clang++-3.8
+      compiler: clang
+      addons: &clang38
+        apt:
+          packages: ["clang-3.8", "g++-7", "python3-pip", "lcov"]
+          sources: *apt_sources
+
+    - env: COMPILER=clang++-3.9
+      compiler: clang
+      addons: &clang39
+        apt:
+          packages: ["clang-3.9", "g++-7", "python3-pip", "lcov"]
+          sources: *apt_sources
+
+    - env: COMPILER=clang++-4.0
+      compiler: clang
+      addons: &clang40
+        apt:
+          packages: ["clang-4.0", "g++-7", "python3-pip", "lcov"]
+          sources: *apt_sources
+
+    - env: COMPILER=clang++-5.0
+      compiler: clang
+      addons: &clang50
+        apt:
+          packages: ["clang-5.0", "g++-7", "python3-pip", "lcov"]
+          sources: *apt_sources
+
+  allow_failures:
+    - env: COMPILER=clang++-3.7
+      compiler: clang
+
+    - env: COMPILER=clang++-3.9
+      compiler: clang
+
+
+install:
+  - wget https://github.com/ninja-build/ninja/releases/download/v1.8.2/ninja-linux.zip && unzip -q ninja-linux.zip -d build-ninja
+  - wget https://github.com/danmar/cppcheck/releases/download/1.81/cppcheck-1.81.zip && unzip -q cppcheck-1.81.zip
+  - cd cppcheck-1.81/ && make SRCDIR=build CFGDIR=cfg CXXFLAGS="-O1 -DNDEBUG" -j2 && cd ..
+  - pip3 install --user meson
+  - pip3 install --user conan
+  - conan remote add bincrafters https://api.bintray.com/conan/bincrafters/public-conan
+  - export PATH="`pwd`/build-ninja:${PATH}"
+  - export PATH="`pwd`/cppcheck-1.81/:${PATH}"
+  - export PATH="~/.local/bin:${PATH}"
+
+before_script:
+  - export CXX=$COMPILER
+  - mkdir debug && cd debug
+  - conan install ..
+  - conan build ..
+  - meson configure -Dbuildtype=debug
+  - meson configure -Dwarning_level=3
+  - if [[ "${COMPILER}" == clang++* ]]; then meson configure -Db_sanitize="address,undefined"; fi;
+  - meson configure -Db_coverage=true
+  - ninja
+  - cd ..
+  - mkdir release-sanitize && cd release-sanitize
+  - conan install ..
+  - conan build ..
+  - meson configure -Dbuildtype=release
+  - meson configure -Dwarning_level=3
+  - if [[ "${COMPILER}" == clang* ]]; then meson configure -Db_sanitize="address,undefined"; fi;
+  - ninja
+  - cd ..
+  - mkdir release && cd release
+  - conan install ..
+  - conan build ..
+  - meson configure -Dbuildtype=release
+  - meson configure -Dwarning_level=3
+  - ninja
+  - cd ..
+
+script:
+  - cd release && ./test/mainTest && ./test/colorTest && ./test/envTermMissing
+  - ninja cppcheck && cd ..
+
+after_success:
+  - cd debug && ./test/mainTest && ./test/colorTest && ./test/envTermMissing
+  - bash <(curl -s https://codecov.io/bash)
+  - cd .. && cd release-sanitize && ./test/mainTest && ./test/colorTest && ./test/envTermMissing
+
+notifications:
+  email: false
diff --git a/packages/rang/LICENSE b/packages/rang/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..cf1ab25da0349f84a3fdd40032f0ce99db813b8b
--- /dev/null
+++ b/packages/rang/LICENSE
@@ -0,0 +1,24 @@
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <http://unlicense.org>
diff --git a/packages/rang/README.md b/packages/rang/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..73967f36715af1a90d86b9bb787ccb716b6dd767
--- /dev/null
+++ b/packages/rang/README.md
@@ -0,0 +1,159 @@
+# rang [![Build Status](https://travis-ci.org/agauniyal/rang.svg?branch=master)](https://travis-ci.org/agauniyal/rang) [![Build status](https://ci.appveyor.com/api/projects/status/jqpdoelli38h2a7w?svg=true)](https://ci.appveyor.com/project/agauniyal/rang) [![codecov](https://codecov.io/gh/agauniyal/rang/branch/master/graph/badge.svg)](https://codecov.io/gh/agauniyal/rang) [ ![Download](https://api.bintray.com/packages/agauniyal/rang/rang%3Arang/images/download.svg) ](https://bintray.com/agauniyal/rang/rang%3Arang/_latestVersion)
+
+##### Colors for your Terminal.
+
+![rang-demo](https://cloud.githubusercontent.com/assets/7630575/13501282/0bd00074-e18c-11e5-9848-5bd1f20566d9.gif)
+<details>
+ <summary>Windows Demo</summary>
+
+![rang-windows-demo](https://cloud.githubusercontent.com/assets/11349690/19836886/8134975e-9ebe-11e6-9ee4-c4657784ff3b.gif)
+</details>
+
+
+Example usage
+-------------
+
+```c++
+#include "rang.hpp"
+
+using namespace std;
+using namespace rang;
+
+int main()
+{
+    cout << "Plain old text"
+         << style::bold << "Rang styled text!!"
+         << style::reset << endl;
+}
+```
+
+Dependencies
+------------
+*rang* only depends on [C++ standard library](http://en.cppreference.com/w/cpp/header), `unistd.h` system header on unix and `windows.h` & `io.h` system headers on windows based systems. In other words, you don't need any 3rd party dependencies.
+
+
+Installation
+------------
+
+*rang* is a single header-only library. Put `rang.hpp` in the [include](include) folder directly into the project source tree or somewhere reachable from your project.
+
+Or, if you use the [conan package manager](https://www.conan.io/), follow these steps:
+
+1. Add a reference to *rang* to the *requires* section of your project's `conanfile.txt` file:
+
+        [requires]
+        rang/3.1.0@rang/stable
+
+2. Run conan's install command:
+
+        conan install
+
+
+## How to use
+
+*Rang* uses iostream objects - `cout`/`clog`/`cerr` to apply attributes to output text. Since *rang* aims to support both windows and unix like systems, it takes care of the os specific details and tries to provide a uniform interface. Due to incompatiblities b/w different OS versions, not all kinds of attributes are supported on every system so rang will try to skip the ones which might produce garbage(instead of pushing random ANSI escape codes on your streams). Detection of tty is also handled internally so you don't need to check if application user might redirect output to a file.
+
+> **Need support for non-ansi terminals? Check out [Termdb](https://github.com/agauniyal/termdb) which supports virtually all terminals and their capablities.**
+
+Apart from setting text attributes, you can also ask rang to override its default behaviour through these methods -
+```cpp
+void rang::setControlMode(rang::control);
+```
+where `rang::control` takes
+ - `control::Auto` - Automatically detects whether terminal supports color or not(**Default**)
+ - `control::Off` - Turn off colors completely
+ - `control::Force` - Force colors even if terminal doesn't supports them or output is redirected to non-terminal
+
+```cpp
+void rang::setWinTermMode(rang::winTerm);
+```
+where `rang::winTerm` takes
+ - `winTerm::Auto` - Checks for newer windows and picks Ansi otherwise falls back to Native(**Default**)
+ - `winTerm::Native` - This method is supported in all versions of windows but supports less attributes
+ - `winTerm::Ansi` - This method is supported in newer versions of windows and supports rich variety of attributes
+
+
+Supported attributes with their compatiblity are listed below -
+
+**Text Styles**:
+
+| Code | Linux/Win/Others | Old Win
+| ---- | --------- | ------ |
+| `rang::style::bold`      | yes   | yes   |
+| `rang::style::dim`       | yes   | no    |
+| `rang::style::italic`    | yes   | no    |
+| `rang::style::underline` | yes   | maybe |
+| `rang::style::blink`     | no    | maybe |
+| `rang::style::rblink`    | no    | no    |
+| `rang::style::reversed`  | yes   | yes   |
+| `rang::style::conceal`   | maybe | yes   |
+| `rang::style::crossed`   | yes   | no    |
+
+**Text Color**:
+
+| Code | Linux/Win/Others | Old Win
+| ---- | --------- | ------ |
+| `rang::fg::black`     | yes | yes |
+| `rang::fg::red`       | yes | yes |
+| `rang::fg::green`     | yes | yes |
+| `rang::fg::yellow`    | yes | yes |
+| `rang::fg::blue`      | yes | yes |
+| `rang::fg::magenta`   | yes | yes |
+| `rang::fg::cyan`      | yes | yes |
+| `rang::fg::gray`      | yes | yes |
+
+**Background Color**:
+
+| Code | Linux/Win/Others | Old Win
+| ---- | --------- | ------ |
+| `rang::bg::black`     | yes | yes |
+| `rang::bg::red`       | yes | yes |
+| `rang::bg::green`     | yes | yes |
+| `rang::bg::yellow`    | yes | yes |
+| `rang::bg::blue`      | yes | yes |
+| `rang::bg::magenta`   | yes | yes |
+| `rang::bg::cyan`      | yes | yes |
+| `rang::bg::gray`      | yes | yes |
+
+**Bright Foreground Color**:
+
+| Code | Linux/Win/Others | Old Win
+| ---- | --------- | ------ |
+| `rang::fgB::black`     | yes | yes |
+| `rang::fgB::red`       | yes | yes |
+| `rang::fgB::green`     | yes | yes |
+| `rang::fgB::yellow`    | yes | yes |
+| `rang::fgB::blue`      | yes | yes |
+| `rang::fgB::magenta`   | yes | yes |
+| `rang::fgB::cyan`      | yes | yes |
+| `rang::fgB::gray`      | yes | yes |
+
+**Bright Background Color**:
+
+| Code | Linux/Win/Others | Old Win
+| ---- | --------- | ------ |
+| `rang::bgB::black`     | yes | yes |
+| `rang::bgB::red`       | yes | yes |
+| `rang::bgB::green`     | yes | yes |
+| `rang::bgB::yellow`    | yes | yes |
+| `rang::bgB::blue`      | yes | yes |
+| `rang::bgB::magenta`   | yes | yes |
+| `rang::bgB::cyan`      | yes | yes |
+| `rang::bgB::gray`      | yes | yes |
+
+**Reset Styles/Colors**:
+
+| Code | Linux/Win/Others | Old Win
+| ---- | --------- | ------ |
+| `rang::style::reset`  | yes   | yes |
+| `rang::fg::reset`     | yes   | yes |
+| `rang::bg::reset`     | yes   | yes |
+
+-----
+## My terminal is not detected/gets garbage output!
+
+Check your env variable `TERM`'s value. Then open an issue [here](https://github.com/agauniyal/rang/issues/new) and make sure to mention `TERM`'s value along with your terminal name.
+
+## Redirecting `cout`/`cerr`/`clog` rdbuf?
+
+Rang doesn't interfere if you try to redirect `cout`/`cerr`/`clog` to somewhere else and leaves the decision to the library user. Make sure you've read this [conversation](https://github.com/agauniyal/rang/pull/77#issuecomment-360991652) and check out the example code [here](https://gist.github.com/kingseva/a918ec66079a9475f19642ec31276a21).
diff --git a/packages/rang/appveyor.yml b/packages/rang/appveyor.yml
new file mode 100644
index 0000000000000000000000000000000000000000..89b23a87e97ca0e7a2abd3c12232d303577a6ecb
--- /dev/null
+++ b/packages/rang/appveyor.yml
@@ -0,0 +1,54 @@
+environment:
+  matrix:
+    - arch: x64
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+      compiler: msvc2017
+    - arch: x64
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+      compiler: msvc2015
+
+install:
+  - ps:  wget  'https://github.com/ninja-build/ninja/releases/download/v1.8.2/ninja-win.zip' -OutFile ninja.zip
+  - cmd: 7z x ninja.zip -oC:\ninja > nul
+  - cmd: set PATH=C:\ninja;%PATH%
+
+  - cmd: set MESON_PYTHON_PATH=C:\python35-x64
+  - cmd: set PATH=%MESON_PYTHON_PATH%;%MESON_PYTHON_PATH%\Scripts;%PATH%
+  - ps: $PKG_CONFIG_URL="http://ftp.gnome.org/pub/gnome/binaries/win64/dependencies/pkg-config_0.23-2_win64.zip";
+  - ps: $GLIB_URL="http://ftp.gnome.org/pub/gnome/binaries/win64/glib/2.26/glib_2.26.1-1_win64.zip";
+  - ps: $GETTEXT_URL="http://ftp.gnome.org/pub/gnome/binaries/win64/dependencies/gettext-runtime_0.18.1.1-2_win64.zip";
+  - ps: wget $GLIB_URL -OutFile glib.zip
+  - ps: wget $GETTEXT_URL -OutFile gettext.zip
+  - ps: wget $PKG_CONFIG_URL -OutFile pkg_config.zip
+  - ps: wget 'https://github.com/OpenCppCoverage/OpenCppCoverage/releases/download/release-0.9.6.1/OpenCppCoverageSetup-x64-0.9.6.1.exe' -OutFile coverage_setup.exe
+  - cmd: coverage_setup.exe /VERYSILENT
+
+  - cmd: 7z x glib.zip -oC:\glib > nul
+  - cmd: 7z x gettext.zip -oC:\gettext > nul
+  - cmd: 7z x pkg_config.zip -oC:\pkg_config > nul
+
+  - cmd: set OPENCPPPATH="C:\\Program Files\\OpenCppCoverage"
+  - cmd: set PATH=C:\glib\bin\;C:\gettext\bin\;C:\pkg_config\bin\;%OPENCPPPATH%;%PATH%
+  - cmd: python -m pip install meson conan codecov
+
+  - cmd: if %compiler%==msvc2015 ( call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" %arch% )
+  - cmd: if %compiler%==msvc2017 ( if %arch%==x64 ( call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat"))
+  - cmd: conan remote add bincrafters https://api.bintray.com/conan/bincrafters/public-conan
+
+
+build_script:
+  - cmd: mkdir build && cd build
+  - cmd: conan install ..
+  - cmd: conan build ..
+  - cmd: meson configure -Dbuildtype=debug
+  - cmd: meson configure -Dwarning_level=3
+  - cmd: ninja
+  - cmd: cd test
+  - cmd: mainTest.exe
+  - cmd: colorTest.exe
+  - cmd: envTermMissing.exe
+  - cmd: OpenCppCoverage --sources C:\projects\rang --export_type=binary:envTermMissingReport.bin -- envTermMissing.exe
+  - cmd: OpenCppCoverage --sources C:\projects\rang --export_type=binary:mainTestReport.bin -- mainTest.exe
+  - cmd: OpenCppCoverage --sources C:\projects\rang --export_type=binary:colorTestReport.bin -- colorTest.exe
+  - cmd: OpenCppCoverage --sources C:\projects\rang --export_type=cobertura:overallReport.xml --input_coverage=mainTestReport.bin --input_coverage=envTermMissingReport.bin --input_coverage=colorTestReport.bin
+  - cmd: codecov --root ../.. --no-color --disable gcov -f overallReport.xml
diff --git a/packages/rang/conanfile.py b/packages/rang/conanfile.py
new file mode 100644
index 0000000000000000000000000000000000000000..4ad8ee762d08e5c1a2eb00815fbf74c7de27681c
--- /dev/null
+++ b/packages/rang/conanfile.py
@@ -0,0 +1,24 @@
+from conans import ConanFile, Meson
+
+
+class RangConan(ConanFile):
+    name = "rang"
+    version = "3.1.0"
+    license = "The Unlicense"
+    url = "https://github.com/agauniyal/rang"
+    description = "A Minimal, Header only Modern c++ library for colors in your terminal"
+    generators = "pkg_config"
+    build_requires = "doctest/1.2.6@bincrafters/stable"
+    exports_sources = "*"
+
+    def build(self):
+        meson = Meson(self)
+        meson.configure(cache_build_folder="build")
+        meson.build()
+
+    def package(self):
+        self.copy("*.hpp")
+        self.copy(pattern="LICENSE", dst="licenses", keep_path=False)
+
+    def package_id(self):
+        self.info.header_only()
diff --git a/packages/rang/include/rang.hpp b/packages/rang/include/rang.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..831eda4c5939a9af35fa9c0fc64faebceb8c8cea
--- /dev/null
+++ b/packages/rang/include/rang.hpp
@@ -0,0 +1,502 @@
+#ifndef RANG_DOT_HPP
+#define RANG_DOT_HPP
+
+#if defined(__unix__) || defined(__unix) || defined(__linux__)
+#define OS_LINUX
+#elif defined(WIN32) || defined(_WIN32) || defined(_WIN64)
+#define OS_WIN
+#elif defined(__APPLE__) || defined(__MACH__)
+#define OS_MAC
+#else
+#error Unknown Platform
+#endif
+
+#if defined(OS_LINUX) || defined(OS_MAC)
+#include <unistd.h>
+
+#elif defined(OS_WIN)
+
+#if defined(_WIN32_WINNT) && (_WIN32_WINNT < 0x0600)
+#error                                                                         \
+  "Please include rang.hpp before any windows system headers or set _WIN32_WINNT at least to _WIN32_WINNT_VISTA"
+#elif !defined(_WIN32_WINNT)
+#define _WIN32_WINNT _WIN32_WINNT_VISTA
+#endif
+
+#include <windows.h>
+#include <io.h>
+#include <memory>
+
+// Only defined in windows 10 onwards, redefining in lower windows since it
+// doesn't gets used in lower versions
+// https://docs.microsoft.com/en-us/windows/console/getconsolemode
+#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
+#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
+#endif
+
+#endif
+
+#include <algorithm>
+#include <atomic>
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+
+namespace rang {
+
+/* For better compability with most of terminals do not use any style settings
+ * except of reset, bold and reversed.
+ * Note that on Windows terminals bold style is same as fgB color.
+ */
+enum class style {
+    reset     = 0,
+    bold      = 1,
+    dim       = 2,
+    italic    = 3,
+    underline = 4,
+    blink     = 5,
+    rblink    = 6,
+    reversed  = 7,
+    conceal   = 8,
+    crossed   = 9
+};
+
+enum class fg {
+    black   = 30,
+    red     = 31,
+    green   = 32,
+    yellow  = 33,
+    blue    = 34,
+    magenta = 35,
+    cyan    = 36,
+    gray    = 37,
+    reset   = 39
+};
+
+enum class bg {
+    black   = 40,
+    red     = 41,
+    green   = 42,
+    yellow  = 43,
+    blue    = 44,
+    magenta = 45,
+    cyan    = 46,
+    gray    = 47,
+    reset   = 49
+};
+
+enum class fgB {
+    black   = 90,
+    red     = 91,
+    green   = 92,
+    yellow  = 93,
+    blue    = 94,
+    magenta = 95,
+    cyan    = 96,
+    gray    = 97
+};
+
+enum class bgB {
+    black   = 100,
+    red     = 101,
+    green   = 102,
+    yellow  = 103,
+    blue    = 104,
+    magenta = 105,
+    cyan    = 106,
+    gray    = 107
+};
+
+enum class control {  // Behaviour of rang function calls
+    Off   = 0,  // toggle off rang style/color calls
+    Auto  = 1,  // (Default) autodect terminal and colorize if needed
+    Force = 2  // force ansi color output to non terminal streams
+};
+// Use rang::setControlMode to set rang control mode
+
+enum class winTerm {  // Windows Terminal Mode
+    Auto   = 0,  // (Default) automatically detects wheter Ansi or Native API
+    Ansi   = 1,  // Force use Ansi API
+    Native = 2  // Force use Native API
+};
+// Use rang::setWinTermMode to explicitly set terminal API for Windows
+// Calling rang::setWinTermMode have no effect on other OS
+
+namespace rang_implementation {
+
+    inline std::atomic<control> &controlMode() noexcept
+    {
+        static std::atomic<control> value(control::Auto);
+        return value;
+    }
+
+    inline std::atomic<winTerm> &winTermMode() noexcept
+    {
+        static std::atomic<winTerm> termMode(winTerm::Auto);
+        return termMode;
+    }
+
+    inline bool supportsColor() noexcept
+    {
+#if defined(OS_LINUX) || defined(OS_MAC)
+
+        static const bool result = [] {
+            const char *Terms[]
+              = { "ansi",    "color",  "console", "cygwin", "gnome",
+                  "konsole", "kterm",  "linux",   "msys",   "putty",
+                  "rxvt",    "screen", "vt100",   "xterm" };
+
+            const char *env_p = std::getenv("TERM");
+            if (env_p == nullptr) {
+                return false;
+            }
+            return std::any_of(std::begin(Terms), std::end(Terms),
+                               [&](const char *term) {
+                                   return std::strstr(env_p, term) != nullptr;
+                               });
+        }();
+
+#elif defined(OS_WIN)
+        // All windows versions support colors through native console methods
+        static constexpr bool result = true;
+#endif
+        return result;
+    }
+
+#ifdef OS_WIN
+
+
+    inline bool isMsysPty(int fd) noexcept
+    {
+        // Dynamic load for binary compability with old Windows
+        const auto ptrGetFileInformationByHandleEx
+          = reinterpret_cast<decltype(&GetFileInformationByHandleEx)>(
+            GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),
+                           "GetFileInformationByHandleEx"));
+        if (!ptrGetFileInformationByHandleEx) {
+            return false;
+        }
+
+        HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
+        if (h == INVALID_HANDLE_VALUE) {
+            return false;
+        }
+
+        // Check that it's a pipe:
+        if (GetFileType(h) != FILE_TYPE_PIPE) {
+            return false;
+        }
+
+        // POD type is binary compatible with FILE_NAME_INFO from WinBase.h
+        // It have the same alignment and used to avoid UB in caller code
+        struct MY_FILE_NAME_INFO {
+            DWORD FileNameLength;
+            WCHAR FileName[MAX_PATH];
+        };
+
+        auto pNameInfo = std::unique_ptr<MY_FILE_NAME_INFO>(
+          new (std::nothrow) MY_FILE_NAME_INFO());
+        if (!pNameInfo) {
+            return false;
+        }
+
+        // Check pipe name is template of
+        // {"cygwin-","msys-"}XXXXXXXXXXXXXXX-ptyX-XX
+        if (!ptrGetFileInformationByHandleEx(h, FileNameInfo, pNameInfo.get(),
+                                             sizeof(MY_FILE_NAME_INFO))) {
+            return false;
+        }
+        std::wstring name(pNameInfo->FileName, pNameInfo->FileNameLength / sizeof(WCHAR));
+        if ((name.find(L"msys-") == std::wstring::npos
+             && name.find(L"cygwin-") == std::wstring::npos)
+            || name.find(L"-pty") == std::wstring::npos) {
+            return false;
+        }
+
+        return true;
+    }
+
+#endif
+
+    inline bool isTerminal(const std::streambuf *osbuf) noexcept
+    {
+        using std::cerr;
+        using std::clog;
+        using std::cout;
+#if defined(OS_LINUX) || defined(OS_MAC)
+        if (osbuf == cout.rdbuf()) {
+            static const bool cout_term = isatty(fileno(stdout)) != 0;
+            return cout_term;
+        } else if (osbuf == cerr.rdbuf() || osbuf == clog.rdbuf()) {
+            static const bool cerr_term = isatty(fileno(stderr)) != 0;
+            return cerr_term;
+        }
+#elif defined(OS_WIN)
+        if (osbuf == cout.rdbuf()) {
+            static const bool cout_term
+              = (_isatty(_fileno(stdout)) || isMsysPty(_fileno(stdout)));
+            return cout_term;
+        } else if (osbuf == cerr.rdbuf() || osbuf == clog.rdbuf()) {
+            static const bool cerr_term
+              = (_isatty(_fileno(stderr)) || isMsysPty(_fileno(stderr)));
+            return cerr_term;
+        }
+#endif
+        return false;
+    }
+
+    template <typename T>
+    using enableStd = typename std::enable_if<
+      std::is_same<T, rang::style>::value || std::is_same<T, rang::fg>::value
+        || std::is_same<T, rang::bg>::value || std::is_same<T, rang::fgB>::value
+        || std::is_same<T, rang::bgB>::value,
+      std::ostream &>::type;
+
+
+#ifdef OS_WIN
+
+    struct SGR {  // Select Graphic Rendition parameters for Windows console
+        BYTE fgColor;  // foreground color (0-15) lower 3 rgb bits + intense bit
+        BYTE bgColor;  // background color (0-15) lower 3 rgb bits + intense bit
+        BYTE bold;  // emulated as FOREGROUND_INTENSITY bit
+        BYTE underline;  // emulated as BACKGROUND_INTENSITY bit
+        BOOLEAN inverse;  // swap foreground/bold & background/underline
+        BOOLEAN conceal;  // set foreground/bold to background/underline
+    };
+
+    enum class AttrColor : BYTE {  // Color attributes for console screen buffer
+        black   = 0,
+        red     = 4,
+        green   = 2,
+        yellow  = 6,
+        blue    = 1,
+        magenta = 5,
+        cyan    = 3,
+        gray    = 7
+    };
+
+    inline HANDLE getConsoleHandle(const std::streambuf *osbuf) noexcept
+    {
+        if (osbuf == std::cout.rdbuf()) {
+            static const HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
+            return hStdout;
+        } else if (osbuf == std::cerr.rdbuf() || osbuf == std::clog.rdbuf()) {
+            static const HANDLE hStderr = GetStdHandle(STD_ERROR_HANDLE);
+            return hStderr;
+        }
+        return INVALID_HANDLE_VALUE;
+    }
+
+    inline bool setWinTermAnsiColors(const std::streambuf *osbuf) noexcept
+    {
+        HANDLE h = getConsoleHandle(osbuf);
+        if (h == INVALID_HANDLE_VALUE) {
+            return false;
+        }
+        DWORD dwMode = 0;
+        if (!GetConsoleMode(h, &dwMode)) {
+            return false;
+        }
+        dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
+        if (!SetConsoleMode(h, dwMode)) {
+            return false;
+        }
+        return true;
+    }
+
+    inline bool supportsAnsi(const std::streambuf *osbuf) noexcept
+    {
+        using std::cerr;
+        using std::clog;
+        using std::cout;
+        if (osbuf == cout.rdbuf()) {
+            static const bool cout_ansi
+              = (isMsysPty(_fileno(stdout)) || setWinTermAnsiColors(osbuf));
+            return cout_ansi;
+        } else if (osbuf == cerr.rdbuf() || osbuf == clog.rdbuf()) {
+            static const bool cerr_ansi
+              = (isMsysPty(_fileno(stderr)) || setWinTermAnsiColors(osbuf));
+            return cerr_ansi;
+        }
+        return false;
+    }
+
+    inline const SGR &defaultState() noexcept
+    {
+        static const SGR defaultSgr = []() -> SGR {
+            CONSOLE_SCREEN_BUFFER_INFO info;
+            WORD attrib = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
+            if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),
+                                           &info)
+                || GetConsoleScreenBufferInfo(GetStdHandle(STD_ERROR_HANDLE),
+                                              &info)) {
+                attrib = info.wAttributes;
+            }
+            SGR sgr     = { 0, 0, 0, 0, FALSE, FALSE };
+            sgr.fgColor = attrib & 0x0F;
+            sgr.bgColor = (attrib & 0xF0) >> 4;
+            return sgr;
+        }();
+        return defaultSgr;
+    }
+
+    inline BYTE ansi2attr(BYTE rgb) noexcept
+    {
+        static const AttrColor rev[8]
+          = { AttrColor::black,  AttrColor::red,  AttrColor::green,
+              AttrColor::yellow, AttrColor::blue, AttrColor::magenta,
+              AttrColor::cyan,   AttrColor::gray };
+        return static_cast<BYTE>(rev[rgb]);
+    }
+
+    inline void setWinSGR(rang::bg col, SGR &state) noexcept
+    {
+        if (col != rang::bg::reset) {
+            state.bgColor = ansi2attr(static_cast<BYTE>(col) - 40);
+        } else {
+            state.bgColor = defaultState().bgColor;
+        }
+    }
+
+    inline void setWinSGR(rang::fg col, SGR &state) noexcept
+    {
+        if (col != rang::fg::reset) {
+            state.fgColor = ansi2attr(static_cast<BYTE>(col) - 30);
+        } else {
+            state.fgColor = defaultState().fgColor;
+        }
+    }
+
+    inline void setWinSGR(rang::bgB col, SGR &state) noexcept
+    {
+        state.bgColor = (BACKGROUND_INTENSITY >> 4)
+          | ansi2attr(static_cast<BYTE>(col) - 100);
+    }
+
+    inline void setWinSGR(rang::fgB col, SGR &state) noexcept
+    {
+        state.fgColor
+          = FOREGROUND_INTENSITY | ansi2attr(static_cast<BYTE>(col) - 90);
+    }
+
+    inline void setWinSGR(rang::style style, SGR &state) noexcept
+    {
+        switch (style) {
+            case rang::style::reset: state = defaultState(); break;
+            case rang::style::bold: state.bold = FOREGROUND_INTENSITY; break;
+            case rang::style::underline:
+            case rang::style::blink:
+                state.underline = BACKGROUND_INTENSITY;
+                break;
+            case rang::style::reversed: state.inverse = TRUE; break;
+            case rang::style::conceal: state.conceal = TRUE; break;
+            default: break;
+        }
+    }
+
+    inline SGR &current_state() noexcept
+    {
+        static SGR state = defaultState();
+        return state;
+    }
+
+    inline WORD SGR2Attr(const SGR &state) noexcept
+    {
+        WORD attrib = 0;
+        if (state.conceal) {
+            if (state.inverse) {
+                attrib = (state.fgColor << 4) | state.fgColor;
+                if (state.bold)
+                    attrib |= FOREGROUND_INTENSITY | BACKGROUND_INTENSITY;
+            } else {
+                attrib = (state.bgColor << 4) | state.bgColor;
+                if (state.underline)
+                    attrib |= FOREGROUND_INTENSITY | BACKGROUND_INTENSITY;
+            }
+        } else if (state.inverse) {
+            attrib = (state.fgColor << 4) | state.bgColor;
+            if (state.bold) attrib |= BACKGROUND_INTENSITY;
+            if (state.underline) attrib |= FOREGROUND_INTENSITY;
+        } else {
+            attrib = state.fgColor | (state.bgColor << 4) | state.bold
+              | state.underline;
+        }
+        return attrib;
+    }
+
+    template <typename T>
+    inline void setWinColorAnsi(std::ostream &os, T const value)
+    {
+        os << "\033[" << static_cast<int>(value) << "m";
+    }
+
+    template <typename T>
+    inline void setWinColorNative(std::ostream &os, T const value)
+    {
+        const HANDLE h = getConsoleHandle(os.rdbuf());
+        if (h != INVALID_HANDLE_VALUE) {
+            setWinSGR(value, current_state());
+            // Out all buffered text to console with previous settings:
+            os.flush();
+            SetConsoleTextAttribute(h, SGR2Attr(current_state()));
+        }
+    }
+
+    template <typename T>
+    inline enableStd<T> setColor(std::ostream &os, T const value)
+    {
+        if (winTermMode() == winTerm::Auto) {
+            if (supportsAnsi(os.rdbuf())) {
+                setWinColorAnsi(os, value);
+            } else {
+                setWinColorNative(os, value);
+            }
+        } else if (winTermMode() == winTerm::Ansi) {
+            setWinColorAnsi(os, value);
+        } else {
+            setWinColorNative(os, value);
+        }
+        return os;
+    }
+#else
+    template <typename T>
+    inline enableStd<T> setColor(std::ostream &os, T const value)
+    {
+        return os << "\033[" << static_cast<int>(value) << "m";
+    }
+#endif
+}  // namespace rang_implementation
+
+template <typename T>
+inline rang_implementation::enableStd<T> operator<<(std::ostream &os,
+                                                    const T value)
+{
+    const control option = rang_implementation::controlMode();
+    switch (option) {
+        case control::Auto:
+            return rang_implementation::supportsColor()
+                && rang_implementation::isTerminal(os.rdbuf())
+              ? rang_implementation::setColor(os, value)
+              : os;
+        case control::Force: return rang_implementation::setColor(os, value);
+        default: return os;
+    }
+}
+
+inline void setWinTermMode(const rang::winTerm value) noexcept
+{
+    rang_implementation::winTermMode() = value;
+}
+
+inline void setControlMode(const control value) noexcept
+{
+    rang_implementation::controlMode() = value;
+}
+
+}  // namespace rang
+
+#undef OS_LINUX
+#undef OS_WIN
+#undef OS_MAC
+
+#endif /* ifndef RANG_DOT_HPP */
diff --git a/packages/rang/meson.build b/packages/rang/meson.build
new file mode 100644
index 0000000000000000000000000000000000000000..1af4a10444920899249377cf83dee45b3c53c9eb
--- /dev/null
+++ b/packages/rang/meson.build
@@ -0,0 +1,10 @@
+project('rang', 'cpp', version : '3.1.0',
+		default_options : ['cpp_std=c++11'])
+
+inc = include_directories('include')
+
+doctest = dependency('doctest')
+subdir('test')
+
+run_target('cppcheck', command : ['cppcheck', '--project=' +
+  			join_paths(meson.build_root(), 'compile_commands.json')])
diff --git a/packages/rang/test/colorTest.cpp b/packages/rang/test/colorTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9e834ec54d5ced271830afd3ce869dbf9d5370bc
--- /dev/null
+++ b/packages/rang/test/colorTest.cpp
@@ -0,0 +1,126 @@
+#include "rang.hpp"
+#include <string>
+
+using namespace std;
+using namespace rang;
+
+void printHeading(const string &heading)
+{
+    cout << '\n'
+         << style::reset << heading << style::reset << bg::reset << fg::reset
+         << endl;
+}
+
+void test_colors(ostream &os, const winTerm opt)
+{
+    setWinTermMode(opt);
+
+    printHeading("Text Style Test:");
+    os << style::bold << " Bold " << style::reset;
+    os << style::italic << " Italic " << style::reset;
+    os << style::underline << " Underlined " << style::reset;
+    os << style::dim << " Dim " << style::reset;
+    os << style::conceal << " Conceal " << style::reset;
+    os << style::reversed << " Reversed " << style::reset;
+    os << style::blink << " Blink " << style::reset;
+    os << style::rblink << " rBlink " << style::reset;
+    os << style::crossed << " Crossed " << style::reset << endl;
+
+    printHeading("Background Test:");
+    os << bg::green << " Green " << bg::reset;
+    os << bg::red << " Red " << bg::reset;
+    os << bg::black << " Black " << bg::reset;
+    os << bg::yellow << " Yellow " << bg::reset;
+    os << bg::blue << " Blue " << bg::reset;
+    os << bg::magenta << " Magenta " << bg::reset;
+    os << bg::cyan << " Cyan " << bg::reset;
+    os << bg::gray << " Grey " << bg::reset << endl;
+
+    printHeading("Foreground Test:");
+    os << fg::green << " Green " << fg::reset;
+    os << fg::red << " Red " << fg::reset;
+    os << fg::black << " Black " << fg::reset;
+    os << fg::yellow << " Yellow " << fg::reset;
+    os << fg::blue << " Blue " << fg::reset;
+    os << fg::magenta << " Magenta " << fg::reset;
+    os << fg::cyan << " Cyan " << fg::reset;
+    os << fg::gray << " Grey " << fg::reset << endl;
+
+    printHeading("Bright Background Test:");
+    os << bgB::green << " Green " << bg::reset;
+    os << bgB::red << " Red " << bg::reset;
+    os << bgB::black << " Black " << bg::reset;
+    os << bgB::yellow << " Yellow " << bg::reset;
+    os << bgB::blue << " Blue " << bg::reset;
+    os << bgB::magenta << " Magenta " << bg::reset;
+    os << bgB::cyan << " Cyan " << bg::reset;
+    os << bgB::gray << " Grey " << bg::reset << endl;
+
+    printHeading("Bright Foreground Test:");
+    os << fgB::green << " Green " << fg::reset;
+    os << fgB::red << " Red " << fg::reset;
+    os << fgB::black << " Black " << fg::reset;
+    os << fgB::yellow << " Yellow " << fg::reset;
+    os << fgB::blue << " Blue " << fg::reset;
+    os << fgB::magenta << " Magenta " << fg::reset;
+    os << fgB::cyan << " Cyan " << fg::reset;
+    os << fgB::gray << " Grey " << fg::reset << endl;
+}
+
+void enumerateWinTerms()
+{
+    cout << endl;
+    cout << "_________________________________________________________________";
+    cout << "\n\n"
+         << style::reset << style::bold << "Printing for WinTerm = Auto"
+         << style::reset << bg::reset << fg::reset << '\n';
+    cout << "_________________________________________________________________";
+    test_colors(cout, winTerm::Auto);
+    test_colors(clog, winTerm::Auto);
+    test_colors(cerr, winTerm::Auto);
+    cout << "-------------------------------------------------------------\n\n";
+
+    cout << endl;
+    cout << "_________________________________________________________________";
+    cout << "\n\n"
+         << style::reset << style::bold << "Printing for WinTerm = Ansi"
+         << style::reset << bg::reset << fg::reset << '\n';
+    cout << "_________________________________________________________________";
+    test_colors(cout, winTerm::Ansi);
+    test_colors(clog, winTerm::Ansi);
+    test_colors(cerr, winTerm::Ansi);
+    cout << "-------------------------------------------------------------\n\n";
+
+    cout << endl;
+    cout << "_________________________________________________________________";
+    cout << "\n\n"
+         << style::reset << style::bold << "Printing for WinTerm = Native"
+         << style::reset << bg::reset << fg::reset << '\n';
+    cout << "_________________________________________________________________";
+    test_colors(cout, winTerm::Native);
+    test_colors(clog, winTerm::Native);
+    test_colors(cerr, winTerm::Native);
+    cout << "-------------------------------------------------------------\n\n";
+}
+
+int main()
+{
+    cout << "\n\n\n"
+         << style::reset << style::underline << style::bold << "Control = Auto"
+         << style::reset << bg::reset << fg::reset << endl;
+    setControlMode(control::Auto);
+    enumerateWinTerms();
+
+    cout << "\n\n\n"
+         << style::reset << style::underline << style::bold
+         << "Control = Force " << style::reset << bg::reset << fg::reset
+         << endl;
+    setControlMode(control::Force);
+    enumerateWinTerms();
+
+    cout << "\n\n\n"
+         << style::reset << style::underline << style::bold << "Control = Off "
+         << style::reset << bg::reset << fg::reset << endl;
+    setControlMode(control::Off);
+    enumerateWinTerms();
+}
diff --git a/packages/rang/test/envTermMissing.cpp b/packages/rang/test/envTermMissing.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1bfb5540e7f6809bd77caacc6e6771b05fd8ea2f
--- /dev/null
+++ b/packages/rang/test/envTermMissing.cpp
@@ -0,0 +1,24 @@
+#include "rang.hpp"
+#include <cstdlib>
+
+using std::cout;
+using std::endl;
+using std::getenv;
+
+int main()
+{
+#if defined(WIN32) || defined(_WIN32) || defined(_WIN64)
+    return 0;
+#else
+    const auto TERM = getenv("TERM");
+    if (TERM != nullptr) {
+        cout << "Unsetting $PATH: " << TERM << '\n';
+        unsetenv("TERM");
+    }
+    cout << rang::fg::green << "===NO COLORS AS FALLBACK===" << endl;
+    if (TERM != nullptr) {
+        cout << "Setting $PATH: " << TERM << '\n';
+        setenv("TERM", TERM, 1);
+    }
+#endif
+}
diff --git a/packages/rang/test/meson.build b/packages/rang/test/meson.build
new file mode 100644
index 0000000000000000000000000000000000000000..a8f2a46668d6f2be227aabe521903e717d5e5fac
--- /dev/null
+++ b/packages/rang/test/meson.build
@@ -0,0 +1,9 @@
+mainTest = executable('mainTest', 'test.cpp', include_directories : inc,
+        dependencies : doctest)
+test('mainTest', mainTest)
+
+colorTest = executable('colorTest', 'colorTest.cpp', include_directories : inc)
+test('colorTest', colorTest)
+
+envTermMissing = executable('envTermMissing', 'envTermMissing.cpp', include_directories : inc)
+test('envTermMissing', envTermMissing)
diff --git a/packages/rang/test/test.cpp b/packages/rang/test/test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4853066b214e4500a30345b35003d59ad75995d0
--- /dev/null
+++ b/packages/rang/test/test.cpp
@@ -0,0 +1,350 @@
+#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
+#include "doctest.h"
+
+#include "rang.hpp"
+#include <fstream>
+#include <string>
+
+using namespace std;
+using namespace rang;
+
+#if defined(__unix__) || defined(__unix) || defined(__linux__)
+#define OS_LINUX
+#elif defined(WIN32) || defined(_WIN32) || defined(_WIN64)
+#define OS_WIN
+#elif defined(__APPLE__) || defined(__MACH__)
+#define OS_MAC
+#else
+#error Unknown Platform
+#endif
+
+
+TEST_CASE("Rang printing with control::Off and cout")
+{
+    const string s        = "Hello World";
+    const string fileName = "outoutoutout.txt";
+
+    setControlMode(control::Off);
+
+    SUBCASE("WinTerm = Native")
+    {
+        setWinTermMode(winTerm::Native);
+        ofstream out(fileName);
+        streambuf *coutbuf = cout.rdbuf();
+        cout.rdbuf(out.rdbuf());
+        cout << fg::blue << s << style::reset;
+        cout.rdbuf(coutbuf);
+        out.close();
+
+        ifstream in(fileName);
+        string output;
+        getline(in, output);
+
+        REQUIRE(s == output);
+    }
+
+    SUBCASE("WinTerm = Auto")
+    {
+        setWinTermMode(winTerm::Auto);
+
+        ofstream out(fileName);
+        streambuf *coutbuf = cout.rdbuf();
+        cout.rdbuf(out.rdbuf());
+        cout << fg::blue << s << style::reset;
+        cout.rdbuf(coutbuf);
+        out.close();
+
+        ifstream in(fileName);
+        string output;
+        getline(in, output);
+
+        REQUIRE(s == output);
+    }
+
+    SUBCASE("WinTerm = Ansi")
+    {
+        setWinTermMode(winTerm::Ansi);
+
+        ofstream out(fileName);
+        streambuf *coutbuf = cout.rdbuf();
+        cout.rdbuf(out.rdbuf());
+        cout << fg::blue << s << style::reset;
+        cout.rdbuf(coutbuf);
+        out.close();
+
+        ifstream in(fileName);
+        string output;
+        getline(in, output);
+
+        REQUIRE(s == output);
+    }
+}
+
+TEST_CASE("Rang printing with control::Force and cout")
+{
+    const string s        = "Hello World";
+    const string fileName = "outoutoutout.txt";
+
+    setControlMode(control::Force);
+
+    SUBCASE("WinTerm = Native")
+    {
+        setWinTermMode(winTerm::Native);
+        ofstream out(fileName);
+        streambuf *coutbuf = cout.rdbuf();
+        cout.rdbuf(out.rdbuf());
+        cout << fg::blue << s << style::reset;
+        cout.rdbuf(coutbuf);
+        out.close();
+
+        ifstream in(fileName);
+        string output;
+        getline(in, output);
+
+#if defined(OS_LINUX) || defined(OS_MAC)
+        REQUIRE(s != output);
+        REQUIRE(s.size() < output.size());
+#elif defined(OS_WIN)
+        REQUIRE(s == output);
+#endif
+    }
+
+    SUBCASE("WinTerm = Ansi")
+    {
+        setWinTermMode(winTerm::Ansi);
+
+        ofstream out(fileName);
+        streambuf *coutbuf = cout.rdbuf();
+        cout.rdbuf(out.rdbuf());
+        cout << fg::blue << s << style::reset;
+        cout.rdbuf(coutbuf);
+        out.close();
+
+        ifstream in(fileName);
+        string output;
+        getline(in, output);
+
+        REQUIRE(s != output);
+        REQUIRE(s.size() < output.size());
+    }
+}
+
+TEST_CASE("Rang printing with control::Off and cerr")
+{
+    const string s        = "Hello World";
+    const string fileName = "outoutoutout.txt";
+
+    setControlMode(control::Off);
+
+    SUBCASE("WinTerm = Native")
+    {
+        setWinTermMode(winTerm::Native);
+        ofstream out(fileName);
+        streambuf *cerrbuf = cerr.rdbuf();
+        cerr.rdbuf(out.rdbuf());
+        cerr << fg::blue << s << style::reset;
+        cerr.rdbuf(cerrbuf);
+        out.close();
+
+        ifstream in(fileName);
+        string output;
+        getline(in, output);
+
+        REQUIRE(s == output);
+    }
+
+    SUBCASE("WinTerm = Auto")
+    {
+        setWinTermMode(winTerm::Auto);
+
+        ofstream out(fileName);
+        streambuf *cerrbuf = cerr.rdbuf();
+        cerr.rdbuf(out.rdbuf());
+        cerr << fg::blue << s << style::reset;
+        cerr.rdbuf(cerrbuf);
+        out.close();
+
+        ifstream in(fileName);
+        string output;
+        getline(in, output);
+
+        REQUIRE(s == output);
+    }
+
+    SUBCASE("WinTerm = Ansi")
+    {
+        setWinTermMode(winTerm::Ansi);
+
+        ofstream out(fileName);
+        streambuf *cerrbuf = cerr.rdbuf();
+        cerr.rdbuf(out.rdbuf());
+        cerr << fg::blue << s << style::reset;
+        cerr.rdbuf(cerrbuf);
+        out.close();
+
+        ifstream in(fileName);
+        string output;
+        getline(in, output);
+
+        REQUIRE(s == output);
+    }
+}
+
+TEST_CASE("Rang printing with control::Force and cerr")
+{
+    const string s        = "Hello World";
+    const string fileName = "outoutoutout.txt";
+
+    setControlMode(control::Force);
+
+    SUBCASE("WinTerm = Native")
+    {
+        setWinTermMode(winTerm::Native);
+        ofstream out(fileName);
+        streambuf *cerrbuf = cerr.rdbuf();
+        cerr.rdbuf(out.rdbuf());
+        cerr << fg::blue << s << style::reset;
+        cerr.rdbuf(cerrbuf);
+        out.close();
+
+        ifstream in(fileName);
+        string output;
+        getline(in, output);
+
+#if defined(OS_LINUX) || defined(OS_MAC)
+        REQUIRE(s != output);
+        REQUIRE(s.size() < output.size());
+#elif defined(OS_WIN)
+        REQUIRE(s == output);
+#endif
+    }
+
+    SUBCASE("WinTerm = Ansi")
+    {
+        setWinTermMode(winTerm::Ansi);
+
+        ofstream out(fileName);
+        streambuf *cerrbuf = cerr.rdbuf();
+        cerr.rdbuf(out.rdbuf());
+        cerr << fg::blue << s << style::reset;
+        cerr.rdbuf(cerrbuf);
+        out.close();
+
+        ifstream in(fileName);
+        string output;
+        getline(in, output);
+
+        REQUIRE(s != output);
+        REQUIRE(s.size() < output.size());
+    }
+}
+
+TEST_CASE("Rang printing with control::Off and clog")
+{
+    const string s        = "Hello World";
+    const string fileName = "outoutoutout.txt";
+
+    setControlMode(control::Off);
+
+    SUBCASE("WinTerm = Native")
+    {
+        setWinTermMode(winTerm::Native);
+        ofstream out(fileName);
+        streambuf *clogbuf = clog.rdbuf();
+        clog.rdbuf(out.rdbuf());
+        clog << fg::blue << s << style::reset;
+        clog.rdbuf(clogbuf);
+        out.close();
+
+        ifstream in(fileName);
+        string output;
+        getline(in, output);
+
+        REQUIRE(s == output);
+    }
+
+    SUBCASE("WinTerm = Auto")
+    {
+        setWinTermMode(winTerm::Auto);
+
+        ofstream out(fileName);
+        streambuf *clogbuf = clog.rdbuf();
+        clog.rdbuf(out.rdbuf());
+        clog << fg::blue << s << style::reset;
+        clog.rdbuf(clogbuf);
+        out.close();
+
+        ifstream in(fileName);
+        string output;
+        getline(in, output);
+
+        REQUIRE(s == output);
+    }
+
+    SUBCASE("WinTerm = Ansi")
+    {
+        setWinTermMode(winTerm::Ansi);
+
+        ofstream out(fileName);
+        streambuf *clogbuf = clog.rdbuf();
+        clog.rdbuf(out.rdbuf());
+        clog << fg::blue << s << style::reset;
+        clog.rdbuf(clogbuf);
+        out.close();
+
+        ifstream in(fileName);
+        string output;
+        getline(in, output);
+
+        REQUIRE(s == output);
+    }
+}
+
+TEST_CASE("Rang printing with control::Force and clog")
+{
+    const string s        = "Hello World";
+    const string fileName = "outoutoutout.txt";
+
+    setControlMode(control::Force);
+
+    SUBCASE("WinTerm = Native")
+    {
+        setWinTermMode(winTerm::Native);
+        ofstream out(fileName);
+        streambuf *clogbuf = clog.rdbuf();
+        clog.rdbuf(out.rdbuf());
+        clog << fg::blue << s << style::reset;
+        clog.rdbuf(clogbuf);
+        out.close();
+
+        ifstream in(fileName);
+        string output;
+        getline(in, output);
+
+#if defined(OS_LINUX) || defined(OS_MAC)
+        REQUIRE(s != output);
+        REQUIRE(s.size() < output.size());
+#elif defined(OS_WIN)
+        REQUIRE(s == output);
+#endif
+    }
+
+    SUBCASE("WinTerm = Ansi")
+    {
+        setWinTermMode(winTerm::Ansi);
+
+        ofstream out(fileName);
+        streambuf *clogbuf = clog.rdbuf();
+        clog.rdbuf(out.rdbuf());
+        clog << fg::blue << s << style::reset;
+        clog.rdbuf(clogbuf);
+        out.close();
+
+        ifstream in(fileName);
+        string output;
+        getline(in, output);
+
+        REQUIRE(s != output);
+        REQUIRE(s.size() < output.size());
+    }
+}
diff --git a/packages/rang/test_package/conanfile.py b/packages/rang/test_package/conanfile.py
new file mode 100644
index 0000000000000000000000000000000000000000..60cd30a2cb2e1c1377df4fecda9ad2b38cdfbe7b
--- /dev/null
+++ b/packages/rang/test_package/conanfile.py
@@ -0,0 +1,17 @@
+from conans import ConanFile, Meson
+import os
+
+class RangConan(ConanFile):
+    generators = "pkg_config"
+    exports_sources = "*"
+
+    def build(self):
+        meson = Meson(self)
+        meson.configure()
+        meson.build()
+
+    def imports(self):
+        self.copy("*.hpp")
+
+    def test(self):
+        self.run(".%svisualTest" % os.sep)
diff --git a/packages/rang/test_package/meson.build b/packages/rang/test_package/meson.build
new file mode 100644
index 0000000000000000000000000000000000000000..7930ce6a9bb0d5cae49361fbae9f6f5054199b40
--- /dev/null
+++ b/packages/rang/test_package/meson.build
@@ -0,0 +1,7 @@
+project('rang', 'cpp', version : '3.1.0',
+		default_options : ['cpp_std=c++11'])
+
+inc = include_directories('include')
+
+visualTest = executable('visualTest', 'visualTest.cpp', include_directories : inc)
+test('visualTest', visualTest)
diff --git a/packages/rang/test_package/visualTest.cpp b/packages/rang/test_package/visualTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a71255e1c96e7798519af7db0e78a8cdb84aa6b5
--- /dev/null
+++ b/packages/rang/test_package/visualTest.cpp
@@ -0,0 +1,13 @@
+#include "rang.hpp"
+#include <string>
+
+using namespace std;
+using namespace rang;
+
+int main()
+{
+    cout << endl
+         << style::reset << bg::green << fg::gray << style::bold
+         << " Rang works! " << bg::reset << fg::reset << style::reset << '\n'
+         << endl;
+}