Если от IBM инструментов уже немного устал

С вами на связи Артур Яхин, я из команды разработчиков backend-а Альфа-Банка. Сегодня я расскажу Вам о том, как мы сделали свой мультитул для разработки бизнесовых продуктов на базе VS Code, устраивайтесь поудобнее и поехали!

Немного истории

4 года назад я начал кампанию по импортозамещению инструментов разработки центральной АБС. Решиться на это было непросто, но, так сказать, наболело, и не без причин. Задача создания инструментов разработки всегда была и остаётся весьма и весьма сложной. В нашем случае всё ещё усложнялось тем, что технологический стек, под который нам нужно было создать весь этот парк, слабо распространён в России, и в мире очень мало open source решений для создания подобного инструментария. Стэк таков:

  1. IBM Power — сервер, ранее более известный как AS400.

  2. IBM i — операционная система.

  3. IBM DB2 for i — СУБД интегрированная в IBM i.

  4. RPG — язык программирования, написанный специально под IBM i.

  5. SQL — язык запросов.

  6. IBM RDi — IDE для разработки на основе Eclipse.

  7. IBM Access Client Solutions — терминал и SQL-клиент в одной упаковке.

  8. АБС Equation — система управления банковскими данными: клиентами, счетами, проводками и т.д.

Это терминал IBM i, более известный как «Green Screen», с помощью которого мы можем выполнять множество различных действий, таких, как разработка, отладка, администрирование.

Green Screen.png
Green Screen

Тема с IBM i, «Green Screen» и RPG уже подробно рассмотрена в других статьях на Хабре, поэтому здесь мы об этом не будем говорить:

О разработке интерактивных приложений под ОС IBM i (aka AS/400)
Здравствуйте, уважаемые читатели. Меня зовут Владимир Лебедев, я работаю в Альфа-Банке и занимаюсь т...
habr.com
IBM System i (aka AS/400) — Как мы делали автотесты приложений зеленого экрана
Привет! Меня зовут Антон Воробьев, я отвечаю в Альфа-Банке за разработку приложений для централизова...
habr.com

RDi выглядит как Eclipse, которым он и является:

RDi.webp
RDi

IBM i SQL-клиент:

RunSQLScripts.jpg
RunSQLScripts

На тот момент из альтернатив практически ничего не было. Да и сейчас не сказать, что их много. Самый интересный вариант — Code For IBM i.

Инструменты от IBM — IDE Rational Developer For i (RDi) и Access Client Solutions (SQL-клиент + терминал) — доминировали и доминируют на рынке. Эти инструменты многим чем не устраивали, были закрыты для правок и практически не поддерживались. Когда возникает проблема с каким-то инструментом, то она не решается, а проблемы и раздражение копятся. Да, они маленькие, но они копятся. 

Я, например, устал переключаться между окнами приложений, потому что их десяток: в одном окне одно делаешь, в другом другое, в пятнадцатом ещё что-то, а тут ещё коннект упал. Разумеется, речь не только про инструменты разработчиков на IBM i — всегда есть еще добрая десятка (а то и больше) внутренних порталов, где нам всегда что-то нужно.

В конце концов, надоело постоянно вводить пароль-логин там, где можно обойтись без этого, не нарушая при этом требований безопасности. Встроенная Kerberos-аутентификация в дальнейшем облегчает жизнь, но всё равно всегда требуется её сначала настроить. Я вообще не хочу помнить о логине и пароле без необходимости — я хочу разрабатывать.

Поискав что-то на просторах интернета, стало понятно, что очень многое нужно сделать с нуля. Появилась идея, как это сделать, с чего начать и, наверное, что самое важное в таких обстоятельствах, — желание и время. Базовым редактором кода я решил взять Visual Studio Code: open source, огромное сообщество и такое же количество плагинов.

На следующем этапе уже своими силами нам удалось создать достаточно мощный набор инструментов на базе того самого VS Code.

  1. iDebugger — отладка кода программ на IBM i.

  2. MixRpgParser — ANTLR парсер для языка RPG.

  3. SonarqubeRpgPlugin — плагин Sonarqube для статического анализа языка RPG. Используется также в качестве линтера без подключения к серверу SonarQube.

  4. iCompile — компиляция кодов IBM i.

  5. iTools — пакет утилит для работы с IBM i и не только.

  6. iDocs — плагин документации по IBM i и не только.

  7. Interpreter — универсальный исполнитель команд: от выполнения SQL и REST-запросов до интерпретации статически компилируемых языков программирования.

  8. TestEngine — библиотека юнит и функционального тестирования.

iTools_Architecture.excalidraw.png
iTools_Architecture.excalidraw

Пройдёмся по каждому из пунктов, уверен, вам будет о чем почитать!

iDebugger

Первой «жертвой» нашей кампании по импортозамещению из всего многообразия инструментов разработки стал, как ни странно, отладчик.

Все версии разных исполнений этого весьма и весьма сложного инструмента оставляли желать лучшего. Постоянные вылеты, сброс настроек, баги и отдельный набор окошек в RDi для отладки IBM i-программ — под всё это регулярно приходилось подстраиваться, особенно когда разработка шла на разных языках. Частая история: при очередном дефекте в отладке RDi — дебаг в Green Screen. Пожалуй, самый стабильный вариант, но со своим «шармом».

Безусловно, всё то, что было создано до нас, — это сложнейшие программные комплексы. И этими программами успешно пользуются во всём мире, но для нас уже накопилось достаточно много багов и вопросов, с которыми я не хотел мириться.

Первые два года работы по плагинам были чисто на моём личном энтузиазме и в свободное время. Доказать ускорение выхода новых бизнес-продуктов только за счёт отладчика было достаточно трудно по понятным причинам. Поэтому, отбросив все сомнения и вдохновившись «ковидными» ограничениями (разработка дебаггера происходила в период с апреля по июнь 2020 года), я стартанул своё путешествие в новый мир.

Подобный опыт был для меня первым — до этого программы подобного класса разрабатывать не доводилось.

Как всегда, первый вопрос — с чего начать!?

Конечно, в наше время в подобных вопросах первым делом всё начинается с интернета — места, где можно найти всё и даже больше. В процессе выбора инструментов я понимал, что полностью написать полноценную IDE со всеми наворотами с нуля (тогда ещё в одиночку) — задачка с «миллионами звёздочек».

Поэтому первым делом я начал искать варианты open source-редакторов кода с возможностью расширений. Платные варианты я сразу не рассматривал, ибо эта инициатива полностью независима от регулярной деятельности. Отсюда вот такой список кандидатов:

  • Eclipse,

  • Visual Studio Code (VS Code),

  • ILEditor.

Каждый вариант из списка имел тогда свои преимущества и недостатки. Остановился я на VS Code, как уже упоминал. Одни из главных преимуществ VS Code:

  • Отличный текстовый редактор.

  • Плагины для подсветки синтаксиса RPG.

  • Работа с Git.

  • Огромное количество плагинов.

  • Огромное сообщество для развития.

Что ещё важно здесь отметить — заранее заложил, что VS Code не будет очередной «серебряной пулей» от всего. Поэтому предусмотрел возможность переезда на другую платформу, и плагины реализованы на двух важных протоколах: Language Server Protocol (LSP) и Debug Adapter Protocol (DAP).

LSP, DAP.excalidraw.png
LSP, DAP.excalidraw

Эти протоколы решают проблему M x N, где M — количество языков, а N — количество сред разработки. Проблема заключается в том, что встраивание инструментов для работы с языками программирования в среды разработки часто происходит с обязательной привязкой к конкретной среде разработки.

DAP и LSP позволяют не привязываться к конкретной IDE, и при необходимости, «переехать» практически «бесшовно» в другие инструменты, поддерживающие их.

К тому же, если понадобится переезд на инструменты, у которых нет «дружбы» с LSP и DAP, архитектура продумана и для этого. У наших инструментов есть точка входа с понятным и простым интерфейсом, вся основная функциональность реализована на Java.

Возвращаясь к дебаггеру, стоит упомянуть, что для VS Code уже существовал шаблон реализации интеграции отладчика через DAP. Подробнее об этой интеграции можно почитать в статье ниже.

Но этот шаблон про UI-взаимодействие, что, разумеется, являлось только частью реализации.

Помимо VS Code, не обойдём стороной компанию IBM, которая предоставляет пример реализации простейшего дебаггера для IBM i на основе так называемых Debug API. С примером на языке C вы можете ознакомиться по ссылке ниже.

VS Code Mock Debug (frontend) и пример IBM отладчика (backend), казалось бы, уже дали хороший старт. Но познакомившись с этими материалами поближе, понимаешь, что реализация конечной цели намного дальше чем кажется на первый взгляд. Оставалось очень много вопросов, которые нужно было решить:

  • Как все это «подружить» через middle-слой?

  • Что нужно для доработок в backend-части?

  • Что нужно для доработок во frontend-части?

Ответом на все эти вопросы послужит следующее решение:

iDebugger.excalidraw.png
iDebugger.excalidraw

Для реализации middle-части был выбран язык Java в связке с библиотекой JTOpen ( JT400 ). Она позволяет осуществлять соединение с IBM i на сервера IBM Power при помощи так называемых джобов — процессов на IBM i. Выполнение отлаживаемого софта всегда происходит на удалённом сервере, поэтому отладка всегда происходит удаленно.

Для работы отладчика в различных режимах, необходимо поддерживать до 3 активных джобов из-под одного пользователя. Это позволяет использовать отладчик как для отладки программы, выполняющейся в созданном из-под вашего пользователя процессе, так и в процессах, которые Вам изначально неизвестны. Это удалось реализовать путем синхронного и асинхронного взаимодействий, а также их комбинаций на всех слоях. И частая история — именно комбинирование.

Для вызова Java API из Typescript-кода использовалась библиотека node-java bridge (JavaInit на общей диаграмме библиотек), которая осуществляет вызов Java API через библиотеку napi-rs, предоставляя разработчику возможность работать с Java-классами напрямую через Javascript-Typescript-код. Подробнее о таких вызовах вы можете почитать по ссылке ниже.

В Java-классе AS400DebugAdapter через один из процессов отправляется сообщение в backend-слой в ожидающую очередь DBGINQ.DTAQ, из которой считывается команда. Затем вызывается соответствующий Debug API, а результат отправляется в очередь выхода DBGOUTQ.DTAQ. На стороне класса AS400DebugAdapter Java API считывает сообщение из очереди DBGOUTQ.DTAQ и отправляет сообщение о статусе операции во front-часть.

Для пользователя в VS Code это выглядит так:

Доступная функциональность:

  • Step Into, Step Over, Continue, Breakpoints, Exceptions.

  • Service Entry Point.

  • Watch expressions.

  • JobLog в Debug-консоли.

  • Eval expression в Debug-консоли.

  • Conditional breakpoints.

Внешне процесс ничем не отличается от отладки в других языках программирования, что и являлось конечной целью — сделать отладку такой же, как и везде. Есть нюансы, которые существенно улучшены по сравнению с другими отладчиками на IBM i, например, лог джоба, который для удобства попадает сразу в debug-консоль.

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

С уверенностью могу сказать, что до 2023 года это был единственный отладчик для IBM i на VS Code во всем мире.

Позднее вышел отладчик от компании IBM, который опубликован только как плагин для VS Code, без открытого исходного кода. В любом случае новый IBM-отладчик нельзя использовать без установки определённых обновлений на Ваш сервер, что сегодня особенно затруднительно. Эта задача позволила нам окунуться в огромный мир неизведанных технологий и плагинов, который продолжил нас впечатлять на пути к созданию нашей новой экосистемы.

iCompile

После победы над созданием собственного инструмента отладки, моё внимание привлек процесс компиляции наших исходных кодов.

Разумеется, этот процесс давно был выстроен моими коллегами с помощью других утилит. Конечно, в RDI всегда был, есть и будет функционал, позволяющий настроить команды компиляции. А кто-то даже сделал свой плагин для Notepad++ для тех же целей.

Моей целью было создать единую экосистему, в которой присутствует возможность выполнить любую операцию, требуемую при разработке бизнес-продуктов. Быстрый процесс сборки программ — как раз одна из таких фич.

В целом, что касается именно компиляции, то в основном процесс ничем не отличается от других технологий. Есть некоторые особенности, связанные именно с языком RPG, а также с тем, что компиляция активируется на локальной машине и должна происходить на удалённом сервере.

Важное преимущество перед другими технологиями — быстрый анализ полноценного представления кода с раскрытыми директивами /copy. Прежде этот процесс был достаточно болезненным. Единственная возможность смотреть такое представление была только в Green Screen, что, конечно же, крайне неудобно, особенно когда дело касается больших исходных кодов на десятки тысяч строк кода с огромным количеством вставок через директиву /copy. С помощью этой директивы вы можете сделать вставку любой части кода, поэтому без анализа раскрытого кода бывало очень тяжело делать доработки. В RDi функционал позволяет смотреть каждую вставку только отдельно от исходника, и, ко всему прочему, не хватало гибких фильтров сообщений, выдаваемых компилятором.

Для реализации процесса компиляции первым делом, как и в случае с дебаггером, изучил шаблоны VS Code Extension Samples. На этом этапе пока ещё я не стал стрелять из LSP-пушки по воробьям, благодаря чему первая версия iCompile получилась всего за неделю. Middle, уже стандартно, на Java , и включает в себя следующие компоненты:

  • iCompile — точка входа в компиляцию;

  • iUtilities — базовые классы для обработки любых сообщений;

  • iSession — библиотека, отвечающая за соединение с IBM i через JT400.

iCompile.excalidraw.png
iCompile.excalidraw

Если сравнивать с iDebugger-ом то ситуация несколько проще — не требовалось писать отдельных программ на backend-слое. Но без сюрпризов не обошлось, отладчиком научены.

На примере простой программы рассмотрим, как работает iCompile:

CompileSource.webp
CompileSource

Ломаем код , запускаем компиляцию, внутри библиотеки запускается следующая команда:

CompileCommand.webp
CompileCommand

Вот такие данные забираем из таблицы, сгенерированной компилятором:

CompileErrorTables.webp
CompileErrorTables

В таблице выше есть код сообщения, текст сообщения, уровень серьёзности, позиции в строке, список директив /copy. Разумеется, есть и номер строки, но с ним не всё так просто: для разных типов исходников RPGLE и SQLRPGLE (тот же RPG, только со встроенной поддержкой SQL-инструкций) и настроек компиляции, различается способ указания номера строки в этой таблице.

В случае с SQLRPGLE так вообще используются два компилятора для SQL и RPGLE-инструкций соответственно. Частая история — указанные в таблице строки сообщений на самом деле являются номерами строк в коде с раскрытыми директивами /copy, что требует от нас корректного маппинга разных представлений кода для корректного отображения именно в реальных строках исходного кода.

Разобравшись с номером строки, не забываем про раскрытое представление с /copy-директивами. Его мы используем для корректного маппинга номеров строк с исходным кодом и передаем на вход MixRpg-парсеру (о нём будет рассказано позднее).

Представление получаем из отдельной таблицы:

SrcWithCopy.webp
SrcWithCopy

Результат компиляции:

CompileErrors.webp
CompileErrors

На практике получаем следующее:

iCompile.gif
iCompile

Функциональность: просмотр представления кода с раскрытыми директивами /copy, скачивание всех исходных кодов, вставленных через директиву /copy, фильтрация сообщений компиляции, а также запуск компиляции для следующих языков:

  • SQLRPGLE,

  • RPGLE,

  • DDS PF — создание таблиц БД,

  • DDS LF — создание индексов БД,

  • DDS dspf — создание дисплейных экранов Green Screen,

  • CL ,

  • C/C++.

MixRpgParser

Компиляцией и отладкой в наше время сыт не будешь, поэтому я сразу начал смотреть в сторону реализации полноценных языковых фич: подсветка, IntelliSense, Go To Symbols, Go To Definition и прочее. По подсветке немного повезло — на тот момент уже существовало несколько плагинов, которые предоставляли эту функциональность :

Эти решения основаны на TextMate-языке, с которым у VS Code тесная интеграция. Для получения остальных возможностей регулярками обойтись не получится. Для реализации языковых фич в VS Code предусмотрен Language Server Protocol (LSP). Он позволяет унифицировать работу языкового парсера через JSON-RPC API, выделяя самую тяжёлую по производительности работу с парсером в отдельный процесс. Вы только напишите свой языковой парсер, а LSP сделает всё за Вас!

Если бы всё было так просто... Как всегда, есть множество нюансов, которые выявляются в процессе.

Что же касается написания своего языкового парсера, в нашем случае — это Тьюринг-полный язык, думаю, что эта задача не нуждается в представлении: дни, месяцы и годы можно провести за этой задачей, занимаясь вечной докруткой и огромным пластом автотестов. На тот момент, понимая сложность задачи, сразу хотелось озаботиться не только стандартными языковыми фичами, но и статическим анализом, с которым у нас не сложилось. Ранее мы заказывали одной из компаний создание sonar-плагина для RPG. После полугода ожидания и месяца использования стало понятно — это нам в корне не подходит, и нужно делать всё заново.

Ещё в далёком 2018 году в свободное время занимаясь исследовательскими задачами, я случайно попал на репозиторий RPGLE-parser, который, конечно же, заинтересовал меня своим названием и начинкой. Этот парсер был создан на основе ANTLR — Another Tool For Language Recognition. Это инструмент, позволяющий описать грамматику Вашего языка с помощью специальных правил. После описания грамматики, Вы можете сгенерировать парсер на разных языках в зависимости от ваших потребностей. Ниже показан пример грамматики языка RPG:

RpgParserLexer.webp
RpgParserLexer

В нашем случае я использовал язык Java по соображениям интеграции с другими библиотеками и решил поподробнее познакомиться с этой реализацией. Попробовал для интереса запустить этот движок на наших самых простых исходниках, всего в строк в 50-60. На выходе от всех исходников меня ждала сплошная НЕУДАЧА. Этот парсер совсем не годился для наших исходных кодов.

Основная проблема — наличие нескольких диалектов: Fixed, Free, Full Free. На примере ниже показана разница между диалектами, код идентичен:

FullFree_Free_Fixed.webp
FullFree_Free_Fixed

Некоторые ограничения удалось преодолеть почти сразу, например, убран барьер длины строки во Free — строка не должна превышать 80 символов. Другие адаптировать уже гораздо сложнее — в Fixed и Free диалектах кода присутствуют резервированные первые 5 или 7 байт в строке кода. Они использовались при написании кода в Green Screen для комментариев, меток для указания уровней вложенности кода, операций со строками и т.д.

Когда IBM сделали Full Free диалект для RPG, они запретили напрямую смешивать Full Free с Free и Fixed из-за неоднозначности определения диалекта. Одну строчку можно написать так, что компилятор не поймет как её разбирать. Осталась только возможность совмещать диалекты через директивы /copy, которые и позволяют компилятору устранить нестыковки там, где это требуется. В нашем случае, частая история во всех наших кодах — использование трех диалектов одновременно в так называемом MixRpg-формате.

Смешанный формат кода реализуется, как уже упоминалось, через огромное количество директив /copy. RPGLE-parser умеет работать только с двумя диалектами — Fixed и Free. Таким образом, для разбора смешанного формата кода в случае, когда на вход парсеру подаётся исходный код с раскрытыми директивами /сopy, требуется сдвиг строк Full Free-кода на 7 пробелов вперёд.

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

Поэтому я выбрал альтернативный вариант.

Благодаря богатой кодовой базе, был проведён промежуточный анализ кодов на наличие неоднозначностей. Множество запусков кода для анализа покрытия кода тестами и статического анализа SonarQube показали, что случаев неоднозначности очень мало.

В итоге после множества прогонов был создан достаточно устойчивый алгоритм, осуществляющий сдвиг строк кода на 7 символов вперёд там, где это требуется.

Это позволяет нашему парсеру фактически работать с тремя диалектами одновременно.

После начальной обработки текста изменённый в памяти исходный код передаётся ANTLR-парсеру, который уже разбирает Fixed-Free код. Таким образом, нам удалось сделать то, чего нет даже у IBM!

Несмотря на очередную локальную победу, в одном я не ошибся точно: даже с готовым фундаментом потребовалось множество больших доработок, и такая работа над парсером занимает дни, месяцы и годы…

Но оно того стоило.

Спустя всего полгода удалось получить первые версии парсера, который можно было использовать на наших репозиториях внутри VS Code с локальным статическим анализом и запусками на сервере Sonarqube. На его основе построен процесс разработки кода в наших плагинах.

Ещё из интересного, что мы рассматривали:

  • Использование парсера в качестве основы для LLVM-компилятора RPG-кода на других платформах. Подробнее об этом можно почитать в статье A tutorial on how to write a compiler using LLVM.

  • Автодокументирование кода на основе данных парсинга.

  • Форматтер кода.

SonarQube

Одним из главных направлений использования RPG-парсера стал статический анализ кода — процесс выявления ошибок, потенциальных уязвимостей и несоответствия кода документации, выполняемый без исполнения программного кода и без компиляции. Одним из наиболее популярных инструментов для такого анализа является SonarQube — платформа компании SonarSource. Под этот инструмент мы написали плагин, который можно использовать как на самом сервере, так и без него.

  • Выявлять дефекты на ранних этапах установки софта.

  • Следить за стандартами разработки кода.

  • Обнаруживать несоответствие нефункциональным требованиям.

  • Собирать метрики на основе проведенного анализа кода (дубли, дефекты и т.д.).

  • Собирать статистику по автотестам.

Мы запускаем анализ на разных этапах: разработка, пулл-реквесты, регрессионное тестирование (для подсчёта статистики по автотестам).

Sonarqube.excalidraw.png
Sonarqube.excalidraw

Как мы используем SonarRpg-линтер в IDE:

iToolsLinter.gif
iToolsLinter

iTools

Спустя два года после старта создания нашей платформы руководство одобрило внесение продукта в инфраструктурный проект дирекции, а также выделение ресурсов для дальнейшего развития инструментов. Теперь уже мы развиваем нашу платформу небольшой командой из шести человек. Именно релиз плагина iTools положил начало использованию командами развития наших инструментов.

В iTools используется Language Server Protocol, о котором уже упоминалось ранее. При открытии файла с расширением .rpg исходный код отправляется на IBM i сервер, где происходит его компиляция, получение сообщений и скачивание исходного кода с раскрытыми /copy директивами. Полученный раскрытый код подается на вход MixRpg-парсеру, который разбирает его и создает AST-дерево.

При помощи паттерна Listener идёт анализ полученного дерева и выстраивается основа для Outline представления кода и всех возможностей, связанных с кодом. Помимо непосредственной работы с кодами на разных языках, iTools предоставляет точку входа в Interpreter — исполнитель любых команд.

iTools.excalidraw.png
iTools.excalidraw

Ещё больше возможностей для пользователей ниже.

Подсказки по полям таблицы:

HelpFields.gif
HelpFields

Подсказки по built-in-functions:

HelpBIF.gif
HelpBIF

Outline:

References.gif
References

iDocs

Ещё одна из частых потребностей в любой производственной деятельности — поиск по документации. И речь не только о техническом задании, но и, конечно же, о технической документации: устройстве языка, операционной системы и так далее. У IBM много подобной документации, которая, конечно, присутствует на сайтах и в отдельных книгах. Плюс есть отдельные сайты, где есть информация.

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

В RDi есть свой плагин для локального поиска документации, в которой изложено описание языка RPG в виде HTML. Мы сделали схожий вариант, доработали и получили более широкий набор документации, добавив туда CL, DDS, C/C++, SQL, COBOL.

iDocs.excalidraw.png
iDocs.excalidraw

Пользователь, как и во всех наших инструментах, выполняет минимальный набор действий, при этом не меняя своего ритма профессиональной деятельности и не отвлекаясь на сторонние ресурсы:

Interpreter

Несмотря на достаточно внушительный объём созданных плагинов, стало понятно, что чего-то не хватает. Казалось, что ещё для счастья нужно? Прикрутили свой мешок инструментов в современную IDE с огромным количеством готовых расширений и open-source сообществом — профит.

Но не тут-то было, всё равно остаётся множество нерешённых вопросов.

  • Часто в процессе создания ПО мы используем избыточное количество разных инструментов помимо IDE: SQL-клиент, терминал, браузер, мессенджер, почтовый клиент и много разных других приложений.

  • Хочется выполнять команды из любого текстового окна. Везде всегда требуется выполнять команды, но часто команды можно описать только в маленькой полоске, либо одну команду на строке, либо только при нажатии на треугольник –> в спец. окошке —> в спец. файле, т.е. пройти специальный ритуал. И так до бесконечности.

  • Постоянно требуется уделять внимание коннектам там, где это не требуется.

  • Всегда есть потребность выполнить части кода без значимых трудозатрат, создавать быстрые программы для проверки гипотез, выполнять специальные cl-команды, выполнять SQL-запросы, REST-запросы на месте.

  • Не переключаться между приложениями, а также между окнами: частые походы ради простых операций (много разовых операций) с места на место размывают рабочий фокус.

  • Нужно было нечто среднее между UI <-> терминалом <-> текстовым редактором, и независимое от конкретной IDE.

Как всегда, первым делом посмотрели, что есть из open source решений, но держали в уме, что нужно обязательно иметь тесную интеграцию с нашей платформой плагинов. В итоге остановились на создании своего решения, которое стало выигрышным во всех смыслах, и назвали его интерпретатором. Он позволяет:

  • Запустить ваши команды в любом текстовом окне или файле с любым языковым расширением.

  • Запустить любой RPG-код — фактически, интерпретировать статически компилируемый язык.

  • Запустить SQL-запрос, REST-запрос и так далее.

В нём есть гибкая система настроек, единообразные сообщения во всех командах, переопределение настроек из написанного вами кода. А также:

  • Regexp-фильтрация сообщений от любых источников.

  • Запуск как одной команды, так и скриптом различных команд;.

  • Пользовательские переменные.

Interpreter.excalidraw.png
Interpreter.excalidraw

Для пользователя это выглядит так:

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

Нам достаточно лишь подумать о команде, внести её в любом текстовом окошке и выполнить — больше действий не требуется! Все нужные сообщения появятся рядом с набранной командой, не нужно больше ничего искать в ненужных местах!

На достигнутом мы, конечно же, останавливаться не собираемся.

С помощью интерпретатора мы создаём наш новый TestEngine — плагин для юнит и функционального тестирования. Ранее мы использовали несколько самописных библиотек для тестирования, в которых использовались Cucumber, JUnit, RPGUnit, JT400, Gradle.

В теме тестирования множество своих нюансов, с которыми не так просто совладать: запуск любой программы или функции, отчётность, CI, Asserts.

Есть библиотеки вида RPGUnit, которые решают вопрос с запусками софта, но не решают вопросы с отчётностью и CI. Есть уже готовые библиотеки Cucumber и JUnit, но они написаны под другой стек, и мы писали свою адаптацию через Gradle-плагин и JT400. Но у JT400 есть свои пробелы — не реализован полноценный контракт вызова любых программ, в том числе сервисных. Есть PCML — Program Call Markup Language, который упрощает вызовы, но не решает всех кейсов:

  • нельзя передавать указатели;

  • нет полноценной языковой поддержки;

  • нельзя использовать, если программа не скомпилирована со специальными параметрами.

Вместо JT400 можно использовать библиотеку XML Service, но в ней практически те же самые боли, что и в JT400, только теперь все целиком в XML. И к тому же для использования XML Service в Java нужно было писать ещё один адаптер.

И здесь интерпретатор очень пригодился — решаются множество болей:

  • Унифицированная работа с любыми сообщениями.

  • Запуск любого RPG-кода с любым программным контрактом без всяких «но» и «если», и без XML.

  • Запуск любых IBM i команд.

  • Переменные интерпретатора в любой команде.

  • Генерация любых моков программ.

Сейчас мы делаем интеграцию интерпретатора с Cucumber:

TestEngine.webp
TestEngine

Как вы уже поняли, для такого исполнителя можно реализовать огромное количество различных действий, абсолютно несвязанных друг с другом. Это выстроенный адаптер, который можно использовать где угодно: в IDE, на Web-портале, в командной строке и т. д.

Interpreter_Future.excalidraw.png
Interpreter_Future.excalidraw

Интерпретатор открывает нам дорогу в экосистему, где каждому нужному и важному действию найдётся место. И нет нужды заботиться об исполнении, сообщениях, кнопочках, треугольничках, полосочках и типах файлов. Не важно, где вы: в RPG-коде, в Java-коде, в cucumber-feature файле, Markdown-е, XML-е, в обычном текстовом файле или просто в окне без расширения, в JSON-настройках или в YAML.

Ваша мысль — вот что действительно важно!

Итоги

За 4 года нам удалось создать и внедрить уникальный продукт, аналогов которому в России точно нет. И за последние 1,5 года мы ощутили серьёзный прирост пользователей с различными ролями, из разных подразделений и дирекций.

UserGrowth.webp
UserGrowth

Особенности нашего продукта — полное импортозамещение, контроль исходного кода, и, благодаря интерпретатору, мы теперь не привязаны к IBM i стеку технологий. Мы предлагаем гораздо больше возможностей для всех желающих из разных IT-направлений сделать то, что ранее было невозможным, неудобным и не выходя из своих любимых инструментов.

И мы только начинаем! Присоединяйтесь!

Оставлю ссылку на мой доклад на конференции CoreSystems DevConf 2024. Он частично совпадает со статьей, но будет к ней дополнением.

Комментарии (0)