LINUX.ORG.RU

Программа-заменялка для локализации сообщений и слияния из апстрима

 ,


0

1

Привет, Лор!

Мы сделали одну отечественную программу по всем канонам, т.е. взяли программу с открытыми исходниками, форкнули репозиторий, переименовали программу, внесли 0.1% своих дополнений в алгоритмы и локализовали значительную долю сообщений. Поскольку программа написана на слегка экзотическом языке, который плохо поддерживает локализацию, мы меняли сообщения на русские прямо в исходники, а в каких-то случаях ставили ветвление в зависимости от выбранного языка. В сумме, думаю, порядка 500-800 индивидуальных изменений мы сделали таким путём.

Теперь нам нужно сделать главное, что необходимо для любой правильной отечественной программы, т.е. залить к нам апстрим. Это примерно 3000 коммитов со множественными рефакторингами. Я попытался залить первые 500 и гит сразу залил так, что корректность исходного текста потерялась. Ясно, что разрешить конфликты мы можем, но вряд ли это будет потом работать.

Теперь мне нужна программа-заменялка, которая сделает следующее:

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

Какие программы могут тут помочь? Я нашёл на гитхабе только неживой «лексический diff», это бы могло подойти для начала, но нужен ещё «лексический patch» к нему.

★★★★★

Последнее исправление: hobbit (всего исправлений: 2)

мы меняли сообщения на русские прямо в исходники, а в каких-то случаях ставили ветвление в зависимости от выбранного языка

А что язык настолько кривой, что там нельзя это всё инкапсулировать в библиотеку?

no-such-file ★★★★★
()
Ответ на: комментарий от olelookoe

уже на пункте «смержить наши алгоритмы» сломаемся, потому что как мы найдём наши изменения из 800 изменений и как проконтролируем правильность? Там есть кое-какие тесты, но даже если они упадут, потом можно неделю разбираться, почему упали, т.к. это в основном интеграционные тесты.

В принципе мы можем идти по нашей истории коммитов, их порядка 100, но у нас не будет инструментов контроля.

Пункт search/replace требует на вход список замен, вот его и хочу как-то автоматически получить.

den73 ★★★★★
() автор топика
Ответ на: комментарий от ya-betmen

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

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)

Но всё же, раскудрявый diff/patch бы хотелось. Который бы проводил лексический анализ и определял структуру текста. Т.е. что-то типа IDE, которая умеет в раскраску и свёртку текста. Но чтобы она могла не только раскрасить и свернуть, а ещё делать diff/patch в этой системе координат. Т.е. например, «зайди в 5-й блок сверху в функции foobar и замени там if на else» - чтобы patch был в таких терминах сформулирован. Наверняка ж такой уже запилили 10 раз, просто мне не попался.

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от den73

дело уже сделано

Ну так может переделать?

500-800 индивидуальных изменений

Не выглядит такой уж неподъёмной работой. Учитывая что она уже проделана 1 раз, должно быть намного быстрее.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от no-such-file

да, не выглядит, но «лучше полдня промучаться, а потом за 5 минут долететь». Хотя в данном случае выглядит «полдня промучаться а потом ещё полтора дня скакать на этом постоянно падающем самолёте».

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)

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

Могу предложить форкнуть апстрим, а потом накатить изменения заново вручную, дополнительно сделав нормальную локализацию. В исходниках вообще не-ascii символов быть не должно.

Xenius ★★★★★
()
Ответ на: комментарий от den73

Пункт search/replace требует на вход список замен

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

уже на пункте «смержить наши алгоритмы» сломаемся, потому что как мы найдём наши изменения из 800 изменений и как проконтролируем правильность?

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

olelookoe ★★★
()
Ответ на: комментарий от olelookoe

Не факт, что надо заменять любую строку одинаково во всех местах, где она встречается, или что её вообще надо заменять. gettext умеет с этим как-то обходиться? Никогда не пользовался им. Надо почитать.

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от Xenius

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

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от den73

Сцуко ChatGPT в большом проценте случаев кроет форумы, аки бык овцу. Объяснил мне, что то, что я ищу, называется «статическая локализация» и предложил инструмент xgettext для этого. Мы ведь так скоро совсем обесценимся, что же делать?

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от den73

предложил инструмент xgettext для этого

Каким образом это решает твою проблему? xgettext это прибамбас от gettext чтобы наковырять из исходников строки и сделать messages.po который ты потом переводишь, компиляешь в .mo и используешь вместе с gettext. Но эти _s и т.п. из gettext тебе придётся добавлять всё равно руками.

Т.е. это вариант «переделать и завернуть в библиотеку».

no-such-file ★★★★★
()
Ответ на: комментарий от den73

ChatGPT в большом проценте случаев кроет форумы, аки бык овцу.

RLY?

Объяснил мне, что то, что я ищу, называется «статическая локализация» и предложил инструмент xgettext для этого.

xgettext – часть набора gettext, который тут рекомендовали и к статической локализации отношения не имеет.

что же делать?

Читать доки.

Negorro
()
Ответ на: комментарий от no-such-file

Может и никак, пока разбираюсь. Как минимум, хорошо, что есть понятие static localization, правда, оно не гуглится в сочетании с моим языком, а тут chatgpt уже не осиливает. К сожалению, не могу назвать язык.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

static localization

Ну так это то, что делает gettext и то что я тебе с самого начала предложил. Т.е. вместо

print('Hello');

ты пишешь

print(_s('Hello'))

И эта _s заменяет «hello» на «привет» или что там в текущей локали должно быть. Статическая она потому что исходный текст задан статически. Т.е. если ты динамически собираешь фразу в рантайме, то это не работает, т.е. невозможно заранее знать какая будет фраза и кроме того может быть 100500 разных вариантов.

PS: gettext на самом деле немножко сложнее, она умеет в варианты множественного числа например. Т.е. в зависимости от числа ставить правильную форму, но форму ты сам задаёшь: 1 файл, 2,3,4 файла, 5-20 файлов, 21 файл и т.д.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 3)
Ответ на: комментарий от no-such-file

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

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Тут проблема в том, что работа уже сделана и надо её не потерять.

Одно из самых лучших доказательств ущербности тезиса «а что тут думать, трясти надо!» при разработке ПО. Спиши на повышение опыта, всё равно вот это всё поддерживать совершенно нереально будет с синхронизацией с апстримом.

А на будущее - уже несколько десятков лет все успешно применяют gettext и локали. Просто спрашивай ЛОР, а не чатгпт.

Dimez ★★★★★
()
Ответ на: комментарий от Dimez

Когда мы начинали, ChatGpt вообще ещё не было. Сделали именно по принципу «трясти надо». Но gettext тут не поможет, т.к. 500 мест в исходниках, где литерал будет заменён на _s(«Литерал»), всё равно доставят при последующих слияниях.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Сделали именно по принципу «трясти надо».

Ну вот и получилось как получилось.

Но gettext тут не поможет, т.к. 500 мест в исходниках, где литерал будет заменён на _s(«Литерал»), всё равно доставят при последующих слияниях.

Можно в апстрим обратиться за поддержкой локализации.

Dimez ★★★★★
()
Ответ на: комментарий от den73

Если такую программу писать с нуля, то по-моему руками проще сделать.

sed же. Или ты реплейсы автоматом из диффа наковырять хочешь?

ya-betmen ★★★★★
()
Последнее исправление: ya-betmen (всего исправлений: 1)
Ответ на: комментарий от ya-betmen

sed не особо надёжен, т.к. мне нужно ещё уточнить, какое именно вхождение надо заменить, чтобы это было устойчиво к будущим изменениям (падало, если не сможет в будущем). Желательно автоматически, хотя можно в общем-то и руками, понятно, что уже попадалово состоялось.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

В общем, я понял, что я всё же хочу представление в виде некоего «дерева исходника» и язык запросов к нему, который бы позволил делать поиск, замену и при этом делать это надёжно. Это будет хорошим решением.

den73 ★★★★★
() автор топика
Ответ на: комментарий от vvn_black

Не, не поможет. У гита просто слишком тупой алгоритм определения отличий, это во-первых. Во-вторых, от массовых рефакторингов ничто не поможет в любом случае.

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)

Вообщем готового решения нет, никакие «cherry pick» при таком масштабе работать не будут.

Что нужно сделать:

  1. Надо взять апстрим версию, составить словарь «было» - «стало» для переведенного текста, по этому словарю сделать массовую автозамену в исходниках. Этим закроется основной объем исправлений.
  2. Ветвления логики переносить ручками, обращая внимание на контекст (т.е. опять же не черри-пик)
  3. Остатки и сложные случаи добить вручную.

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

alex0x08 ★★★
()
Ответ на: комментарий от vvn_black

Мне кажется, что поможет прочитать про git flow. Ну и потом отдельно от апстрима делать своё дело, периодически сливая ветки.

Может быть, если разбить нашу работу на несколько веток, которые вести независимо, тогда может помочь. Проблема с гитом в том, что он не позволяет прямо легко отследить источник изменения, поэтому их сложнее контролировать. Но если разбить нашу работу на 3-4 ветки, которые никогда не сливать, каждую из них заливать постоянно в нашу главную ветку, а в каждую из наших веток периодически заливать апстрим, то может быть так и прокатит. Спасибо за идею. Тут, конечно, нужно будет задним числом воссоздать эти 3-4 ветки, но история изменений есть, поэтому это осуществимо, не сказать, что именно просто.

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 4)
Ответ на: комментарий от alex0x08

Ну вот да, только к этому словарю ещё нужна «заливалка», которая будет учитывать возможные неоднозначности. Так-то да, похоже на нормальный план.

den73 ★★★★★
() автор топика

«Поскольку программа написана на слегка экзотическом языке» :-)

поэтому только руками ;-) «слегка экзотичный язык» вряд-ли известен хоть каким-то тулзам.

даже с обычным «С» довольно много мороки - лоцировать в тексте все строчные константы, определить на каком языке, посмотреть можно ли заменять (вдруг алгоритму требуется текст в точности) и на каком этапе (компиляция/рантайм)..

для С - strings,objdump..разобрать программу на запчасти https://www.quut.com/c/ANSI-C-grammar-l-2011.html (не забыть до того дёрнуть препроцессор)

и цель неясна..msgcat левой пяткой через правое плечо ? :-)

MKuznetsov ★★★★★
()
Ответ на: комментарий от den73

Мне кажется, я достаточно чётко цель описал.

вот как-раз таки цель ты не описывал.

Описал свой подход к решению чего-то там, некие дальнейшие шаги и что всё заткнулось :-)

MKuznetsov ★★★★★
()
Ответ на: комментарий от den73

ЦИТАТА:

Я попытался залить первые 500 и гит сразу залил так, что корректность исходного текста потерялась. Ясно, что разрешить конфликты мы можем, но вряд ли это будет потом работать.

Теперь мне нужна программа-заменялка, которая сделает следующее (далее следуют гипотезы про программу на уровне семантики разбирающую/понимающую экзотический язык):

ты хочешь программу которая исправит то что сломал заливая проекты на Git :-)

месье скорее нужно портировать msgcat на экзотический язык и породить инструкцию «проекты на Git заливать только с этим и после вот-таких-действий и проводить вот-эти-вот-тесты», чтобы более не ломать

MKuznetsov ★★★★★
()

не вполне в тему, но кстати про локализацию и «отечественное»

с полгода-год назад попался забавный баг - в одной из очень-отечественных-ос не работал build-скрипт чего-то там (сейчас не вспомню какой софт прибило собрать).

Оказалось что деятели полностью локализовали выхлоп –version почти у всего и билд скрипт не мог найти заветных «version xxx.xxx» в первой строчке и определиться с версиями. По идее неправы оба - и тот кто локализовал всё подряд и авторы билд-скрипта положившиеся на англоязычную локаль

MKuznetsov ★★★★★
()
Ответ на: комментарий от den73

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

Ну меняется и меняется, а с чего бы им быть в разных литералах?

Xenius ★★★★★
()

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

По-моему, это без программиста никак.

Мне всегда хватало kdiff3. Но он со строками работает.

monk ★★★★★
()
Ответ на: комментарий от den73

Мне совестно обращаться в апстрим, поскольку мы не выложим своих переводов (это пермиссивно лицензированное ПО). Да и пошлют они лесом.

Тебе жалко .po файла со строками переводов? Это же даже не код программы.

monk ★★★★★
()
Ответ на: комментарий от den73

https://en.wikipedia.org/wiki/Comparison_of_file_comparison_tools

Там есть вторая табличка и в ней колонка «structured comparison» и в ней - единственный инструмент Pretty Diff с доступными исходниками, который в принципе это умеет.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Pretty Diff

Написано «Currently, the project operates by beautifying code and then comparing the beautified product of the code samples.».

https://semanticdiff.com/?ref=betalist - они что-то говорят про деньги.

Эта штука работает схожим образом. То есть сделать diff так можно, а вот patch уже не получится, так как в diff утрачена информация о «несущественных изменениях».

В общем, я бы «скрипт, где, что и на что заменять» писал бы руками для всех случаев, где не справляется обычный diff3.

monk ★★★★★
()