179 lines
2.9 KiB
Python
179 lines
2.9 KiB
Python
import sys as _sys
|
|
import json as _json
|
|
import yaml as _yaml
|
|
import argparse as _argparse
|
|
|
|
|
|
def convey(
|
|
x,
|
|
fs
|
|
):
|
|
y = x
|
|
for f in fs:
|
|
y = f(y)
|
|
return y
|
|
|
|
|
|
def string_coin(
|
|
template,
|
|
arguments,
|
|
options = None
|
|
):
|
|
options = (
|
|
{
|
|
"character_open": "{{",
|
|
"character_close": "}}"
|
|
}
|
|
|
|
|
(options or {})
|
|
)
|
|
result = template
|
|
for (key, value, ) in arguments.items():
|
|
result = result.replace(
|
|
(
|
|
"%s%s%s"
|
|
% (
|
|
options["character_open"],
|
|
key,
|
|
options["character_close"],
|
|
)
|
|
),
|
|
value
|
|
)
|
|
return result
|
|
|
|
|
|
def file_read(
|
|
path
|
|
):
|
|
handle = open(path, "r")
|
|
content = handle.read()
|
|
handle.close()
|
|
return content
|
|
|
|
|
|
def handle_value(
|
|
value,
|
|
options = None
|
|
):
|
|
options = (
|
|
{
|
|
"indicator": "@",
|
|
}
|
|
|
|
|
(options or {})
|
|
)
|
|
return (
|
|
file_read(value[len(options["indicator"]):])
|
|
if
|
|
value.startswith(options["indicator"])
|
|
else
|
|
value
|
|
)
|
|
|
|
|
|
def data_from_file(
|
|
path
|
|
):
|
|
return (
|
|
{}
|
|
if
|
|
(path is None)
|
|
else
|
|
(
|
|
(
|
|
lambda content: (
|
|
_json.loads(content)
|
|
if
|
|
path.endswith(".json")
|
|
else
|
|
_yaml.safe_load(content)
|
|
)
|
|
) (file_read(path))
|
|
)
|
|
)
|
|
|
|
|
|
def data_from_arguments(
|
|
arguments
|
|
):
|
|
return dict(
|
|
map(
|
|
lambda argument: (
|
|
(
|
|
lambda parts: (
|
|
parts[0],
|
|
handle_value(parts[1]),
|
|
)
|
|
) (argument.split(":", 1))
|
|
),
|
|
(arguments or {})
|
|
)
|
|
)
|
|
|
|
|
|
def main(
|
|
):
|
|
## args
|
|
argument_parser = _argparse.ArgumentParser(
|
|
prog = "coin",
|
|
formatter_class = _argparse.ArgumentDefaultsHelpFormatter,
|
|
description = "transforms an input string (stdin) by processing its placeholders; example: »echo '{{flowers}} are {{color}}' | coin -a flowers:roses -a color:red«",
|
|
)
|
|
argument_parser.add_argument(
|
|
"-d",
|
|
"--data-path",
|
|
type = str,
|
|
default = None,
|
|
metavar = "<data-path>",
|
|
help = "path to JSON or YAML file, containing placeholder assignments (e.g. »{\"flowers\": \"roses\", \"color\": \"red\"}«)",
|
|
)
|
|
argument_parser.add_argument(
|
|
"-a",
|
|
"--argument",
|
|
type = str,
|
|
dest = "arguments",
|
|
action = "append",
|
|
default = None,
|
|
metavar = "<key>:<value>",
|
|
help = "prefixing <value> with '@' causes the value to be interpreted as the path to a text file, whose content shall be used",
|
|
)
|
|
argument_parser.add_argument(
|
|
"-o",
|
|
"--character-open",
|
|
type = str,
|
|
default = "{{",
|
|
metavar = "<character-open>",
|
|
help = "placeholder opening character",
|
|
)
|
|
argument_parser.add_argument(
|
|
"-c",
|
|
"--character-close",
|
|
type = str,
|
|
default = "}}",
|
|
metavar = "<character-close>",
|
|
help = "placeholder closing character",
|
|
)
|
|
args = argument_parser.parse_args()
|
|
|
|
## exec
|
|
content_in = _sys.stdin.read()
|
|
data = (
|
|
data_from_file(args.data_path)
|
|
|
|
|
data_from_arguments(args.arguments)
|
|
)
|
|
content_out = string_coin(
|
|
content_in,
|
|
data,
|
|
{
|
|
"character_open": args.character_open,
|
|
"character_close": args.character_close,
|
|
}
|
|
)
|
|
_sys.stdout.write(content_out)
|
|
|
|
|
|
main()
|
|
|