Skip to content

Commit

Permalink
- Remove Mstch engine
Browse files Browse the repository at this point in the history
- Add varToBool function
  • Loading branch information
navrocky committed Feb 4, 2025
1 parent 40dd6ff commit 52a44b7
Show file tree
Hide file tree
Showing 16 changed files with 159 additions and 163 deletions.
30 changes: 2 additions & 28 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,13 @@ cmake_minimum_required(VERSION 3.5)

set(TARGET muenvsubst)

project(${TAGRET} LANGUAGES CXX)
project(${TARGET} LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(args-parser REQUIRED)
find_package(mbits-mstch REQUIRED)
find_package(inja REQUIRED)

if(CMAKE_BUILD_TYPE STREQUAL "Release")
add_link_options(-static -static-libgcc -static-libstdc++ -s)
endif()

set(SOURCES
src/inja_renderer.cpp
src/inja_renderer.h
src/main.cpp
src/mstch_renderer.cpp
src/mstch_renderer.h
src/tools.cpp
src/tools.h
)

add_executable(${TARGET} ${SOURCES})

target_link_libraries(${TARGET}
args-parser::args-parser
mbits::mstch
pantor::inja
)

include(GNUInstallDirs)
install(TARGETS ${TARGET}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
add_subdirectory(cli)
2 changes: 1 addition & 1 deletion Dockerfile.uclibc
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ RUN set -x && \
cd /build && \
cmake /sources -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release && \
cmake --build . && \
upx -9 --brute muenvsubst
upx -9 --brute cli/muenvsubst
34 changes: 17 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ Substitutes environment variables using one of the templating engines, as

This is a list of supported template engines:

- `mstch` - [Mustache templates](https://github.com/no1msd/mstch)
- `inja` - [Inja templates](https://pantor.github.io/inja/)

One of the advantages of this utility is that it is built in a small static binary without any dependencies.
Expand All @@ -27,23 +26,14 @@ sudo chmod +x /usr/local/bin/muenvsubst
Substitutes environment variables using one of the templating engines, as
envsubst does.
USAGE: ./muenvsubst [ -e, --engine <arg> ] [ -h, --help <arg> ] [ -V,
--version ]
USAGE: ./muenvsubst [ -h, --help <arg> ] [ -V, --version ]
OPTIONAL:
-e, --engine <arg> Use template engine. Supported engines: mstch, inja.
Default is: inja
-h, --help <arg> Print this help.
-h, --help <arg> Print this help.
-V, --version Output version information and exit
-V, --version Output version information and exit
```

## Mustache syntax

[Mstch](https://github.com/no1msd/mstch) library fully supports original [{{ Mustache }}](https://mustache.github.io/)
syntax described [here](https://mustache.github.io/mustache.5.html).

## Inja syntax

[Inja](https://pantor.github.io/inja/) inspired by Python's Jinja and supports subset of original Jinja syntax. It
Expand All @@ -60,6 +50,16 @@ Additional functions:
split(text: string, delimiter: string): string
```

- Convenient convert boolean variable to boolean type:

```
varToBool(varName: string): boolean
```

This function supports strings "true", "yes", "on", "1" for `true` value, other values supposed to be a `false` value.

Example: `set DO_SMTH = varToBool("DO_SMTH")`

- Throw error:

```
Expand All @@ -84,7 +84,7 @@ Hello, John!

- Simple variable substitution:
```sh
echo "Hello, {{ USER }}!" | muenvsubst -e inja
echo "Hello, {{ USER }}!" | muenvsubst
```

then output will be:
Expand All @@ -96,7 +96,7 @@ Hello, John!
- Using variable and function:

```sh
muenvsubst -e inja <<EOF
muenvsubst <<EOF
{%- set username = upper(USER) -%}
Hello, {{ username }}!
EOF
Expand All @@ -111,7 +111,7 @@ Hello, John!
- Render conditional block:
```sh
USE_GREETER=no USE_GOODBYER=yes muenvsubst -e inja << EOF
USE_GREETER=no USE_GOODBYER=yes muenvsubst << EOF
{%- if USE_GREETER=="yes" -%}
Hello, {{ USER }}!
{%- endif -%}
Expand All @@ -130,7 +130,7 @@ Hello, John!
- Using split and loop:
```sh
USERS="John,Mark,Peter" muenvsubst -e inja << EOF
USERS="John,Mark,Peter" muenvsubst << EOF
{%- for user in split(USERS,",") -%}
Hello, {{ user }}!
{%- endfor -%}
Expand Down
2 changes: 1 addition & 1 deletion build-musl.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ docker build --progress plain --tag ${IMAGE_NAME} -f Dockerfile.musl .

id=$(docker create ${IMAGE_NAME})
mkdir -p dist
docker cp $id:/build/muenvsubst ./dist/
docker cp $id:/build/cli/muenvsubst ./dist/
docker rm -v $id
2 changes: 1 addition & 1 deletion build-uclibc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ docker build --progress=plain --tag ${IMAGE_NAME} -f Dockerfile.uclibc .

id=$(docker create ${IMAGE_NAME})
mkdir -p dist
docker cp $id:/build/muenvsubst ./dist/
docker cp $id:/build/cli/muenvsubst ./dist/
docker rm -v $id
25 changes: 25 additions & 0 deletions cli/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
set(TARGET muenvsubst)

find_package(args-parser REQUIRED)
find_package(inja REQUIRED)

set(SOURCES
inja_renderer.cpp
inja_renderer.h
main.cpp
tools.cpp
tools.h
)

add_executable(${TARGET} ${SOURCES})

target_link_libraries(${TARGET}
args-parser::args-parser
pantor::inja
)

include(GNUInstallDirs)
install(TARGETS ${TARGET}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
72 changes: 72 additions & 0 deletions cli/inja_renderer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include "inja_renderer.h"

#include <inja/inja.hpp>
#include <sstream>
#include <stdexcept>

#include "tools.h"

using namespace std;
using namespace std::placeholders;

inline void toLower(string& res)
{
transform(res.begin(), res.end(), res.begin(), [](unsigned char c) { return std::tolower(c); });
}

inline void ltrim(std::string& s)
{
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) { return !std::isspace(ch); }));
}

inline void rtrim(std::string& s)
{
s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) { return !std::isspace(ch); }).base(), s.end());
}

inja::json split(const inja::Arguments& args)
{
if (args.size() != 2)
throw runtime_error("Expected 2 parameters: split(s: string, delimiter: string): string[]");
auto s = args[0]->get<string>();
auto delimiter = args[1]->get<string>();
return stringSplit(s, delimiter);
}

inja::json varToBool(const inja::Arguments& args, inja::json envs)
{
if (args.size() != 1)
throw runtime_error("Expected 1 parameters: toBool(varName: string): bool");
auto name = args[0]->get<string>();
auto val = envs[name];
if (val.is_null())
return false;
if (val.is_boolean())
return val.get<bool>();
if (val.is_string()) {
auto s = val.get<string>();
toLower(s);
ltrim(s);
rtrim(s);
return s == "true" || s == "yes" || s == "on" || s == "1";
}
throw runtime_error((stringstream() << "Unsupported env value type for name " << name).str());
}

inja::json error(const inja::Arguments& args)
{
if (args.size() != 1)
throw runtime_error("Expected 1 parameters: error(message: string)");
auto message = args[0]->get<string>();
throw runtime_error(message);
}

string renderWithInja(const string& tmpl, char** envp)
{
auto envs = getAllEnvs<inja::json>(envp);
inja::Environment env;
env.add_callback("split", bind(split, _1));
env.add_callback("error", bind(error, _1));
env.add_callback("varToBool", [&](const inja::Arguments& args) { return varToBool(args, envs); });
return env.render(tmpl, envs);
}
File renamed without changes.
40 changes: 40 additions & 0 deletions cli/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include <args-parser/all.hpp>

#include "inja_renderer.h"
#include "tools.h"

using namespace std;
using namespace std::placeholders;
using namespace Args;

const char* APP_VERSION = "1.2.0";

int main(int argc, char** argv, char** envp)
{
bool showVersion = false;
CmdLine cmd(argc, argv);
cmd.addHelp(
true, argv[0], "Substitutes environment variables using one of the templating engines, as envsubst does.");
cmd.addArgWithFlagAndName('V', "version", false, false, "Output version information and exit");
try {
cmd.parse();

if (cmd.isDefined("-V")) {
cout << "1.2.0" << endl;
return 0;
}

auto tmpl = readAllInput();
cout << renderWithInja(tmpl, envp);

} catch (const HelpHasBeenPrintedException&) {
return 0;
} catch (const BaseException& x) {
cerr << x.desc() << "\n";
return 1;
} catch (const exception& x) {
cerr << x.what() << "\n";
return 1;
}
return 0;
}
File renamed without changes.
File renamed without changes.
1 change: 0 additions & 1 deletion conanfile.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
[requires]
args-parser/6.3.3
mbits-mstch/1.0.4
inja/3.4.0

[generators]
Expand Down
35 changes: 0 additions & 35 deletions src/inja_renderer.cpp

This file was deleted.

63 changes: 0 additions & 63 deletions src/main.cpp

This file was deleted.

Loading

0 comments on commit 52a44b7

Please sign in to comment.