Dynamic text или как создать полезную утилиту в 60 строк кода

Доброго времени суток!


Я хочу с вами поделиться маленькой историей утилиты, которая создана за несколько часов. Ничего сверхесстественного и суперэволюционного в данной утилите нет, но она облегчает ряд задач, с которыми я сталкиваюсь.


Итак, утилита принимает текст, заменяет ключевые слова (bash) и выводит новый текст. все очень просто.


Примеры использования:


cat yourfile.dxt | dxt

echo "currend date: $(date)" | dxt

image


История


Как и любому программисту, мне приходится очень часто работать с конфиг-файлами, с кодом, в общем с текстом. Исходя из принципа "не повторяйся" (DRY) Как любой уважающий себя ленивый программист, я решил, облегчить работу и снизить рутину. Сделав поверхностный (лень матушка) поиск и не найдя ничего, пришла идея написать простую утилиту. Конечно же я не стал делать парсинг кода, писать свое Абстрактное Синтаксическое Дерево (AST) и разбирать формат входящего текста, так как утилита была сделана для решения конкретной проблемы, и она решает ее. Да и не хотелось тратить много времени на создание чего-то, что нужно только мне, тем более если и так работает.


Первая идея, которая пришла мне в голову это использовать bash, что странно, идея оказалась реалистичной, и на выходе у нас работающий бинарник. На написание программы ушло меньше часа и 60 строк кода (конечно дебаггинг занял больше времени). Исходный код доступен на гитхабе (решил ссылку сюда не добавлять, чтобы не считалось рекламой).


Утилита сырая (нет тестов, возможно небезопасно использовать в продакшене, рекомендуется, проверять конечный код), работоспособность проверена только на macOS


Пример того как я использую **dxt** для конфигурации схожих конфигураций kubernetes

Выводим наш dxt файл (чтобы показать с чем мы работаем и что получится)


$ cat test-deployment.dxt

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: test-$(echo $DEP_NAME)-deployment
  namespace: default
  labels:
    app: test-$(echo $DEP_NAME)-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: test-$(echo $DEP_NAME)-deployment
  template:
    metadata:
      labels:
        app: test-$(echo $DEP_NAME)-deployment
    spec:
      containers:
        - name: test-$(echo $DEP_NAME)
          image: test-$(echo $DEP_NAME):latest
          ports:
            - name: $(echo $DEP_NAME)
              containerPort: 3000
      imagePullSecrets:
        - name: testsecret

Описываем массив нужных нам переменных и проходимся по ним, создавая нужные нам файлы конфигурации ипользую dxt


deps=( users files hashes ); for dep in "${deps[@]}";
do
export DEP_NAME=$dep; cat test-deployment.dxt | dxt > test-$dep-deployment.yml
done

на выходе имеем 3 файла со схожими конфигурациями, но с замененными переменными. Пример одного файла:


$ cat test-users-deployment.yml

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: test-users-deployment
  namespace: default
  labels:
    app: test-users-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: test-users-deployment
  template:
    metadata:
      labels:
        app: test-users-deployment
    spec:
      containers:
        - name: test-users
          image: test-users:latest
          ports:
            - name: users
              containerPort: 3000
      imagePullSecrets:
        - name: testsecret
Метки:
golang, bash, utility, tool, commandline