Рубрики
Tech

Gitlab и кирилица в комментах к коду не в UTF-8 кодировке

Недавно развернул для производственных нужд на работе сервер Gitlab — открытый аналог github.com. Всё бы хорошо, но мы — троглодиты такие — до сих пор пишем код прошивок для наших девайсов под gcc, который не понимает юникод. Поэтому файлы с русскими комментариями сохраняются в кодировке Windows-1251. А Gitlab как-то странно их показывает. Примерно так:

static inline char EncodeCharRuc(char symbol)
{
  if(symbol == 0xA8)                             //бшьтюы 'Ј'
    return 0xA2;
  else if(symbol == 0xB8)                        //бшьтюы 'И'
    return 0xB5;
  else if((symbol >= 0xC0) && (symbol <= 0xFF))	 //бшьтюыћ №ѓёёъюую рыєртшђр ъ№юьх 'И' ш 'Ј'
    return HD44780_table_code[symbol-0xC0];
  else                                           //Тёх юёђрыќэћх ёшьтюыћ
    return symbol;
}

Использован отрывок кода моего коллеги UniBomb‘a

Ruby-гем charlock_holmes, отвечающий за распознавание кодировки исходников и перевода их в UTF-8, почему-то не может сам понять, что подсовывают ему именно Windows-1251. Пришлось ему помочь.

Вот оригинальный файл модуля encode.rb:

# Patch Strings to enable detect_encoding! on views
require 'charlock_holmes/string'
module Gitlab
  module Encode
    extend self

    def utf8 message
      # return nil if message is nil
      return nil unless message

      message.force_encoding("utf-8")
      # return message if message type is binary
      detect = CharlockHolmes::EncodingDetector.detect(message)
      return message if detect[:type] == :binary

      # if message is utf-8 encoding, just return it
      return message if message.valid_encoding?

      # if message is not utf-8 encoding, convert it
      if detect[:encoding]
        message.force_encoding(detect[:encoding])
        message.encode!("utf-8", detect[:encoding], undef: :replace, replace: "", invalid: :replace)
      end

      # ensure message encoding is utf8
      message.valid_encoding? ? message : raise

    # Prevent app from crash cause of encoding errors
    rescue
      encoding = detect ? detect[:encoding] : "unknown"
      "--broken encoding: #{encoding}"
    end

    def detect_encoding message
      return nil unless message

      hash = CharlockHolmes::EncodingDetector.detect(message) rescue {}
      return hash[:encoding] ? hash[:encoding] : nil
    end
  end
end

Проблема возникает в строке номер 21, помеченной комментарием: «Если сообщение не в UTF-8, конвертируем». Кодировка изначально была неверно определена в строке 14, поэтому дальше при попытке конвертации в UTF-8 происходит косяк.

Заменим в строках под номерами 22 и 23 выражение detect[:encoding] на строку "windows-1251" (вместе с кавычками), наглядно намекнув gitlab’у, что он не прав. Теперь этот блок должен выглядеть вот так:

# if message is not utf-8 encoding, convert it
if detect[:encoding]
  message.force_encoding("windows-1251")
  message.encode!("utf-8", "windows-1251", undef: :replace, replace: "", invalid: :replace)
end

Сохраняем. Перезапускаем демона:

sudo service gitlab restart

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

P.S. И да, это костыль, но он вполне допустим в нашем случае, когда сервером пользуется два человека, и код поставляется лишь в двух кодировках: UTF-8 и Windows-1251. Но это баг Чарлока Холмса, ждём апдейтов 🙂

6 ответов к “Gitlab и кирилица в комментах к коду не в UTF-8 кодировке”

Как и предполагал баг c windows-1251 исправлять не собираются.

Для версии gitlab 8.2.0 правки те же самые, а файлы которые нужно править находятся тут:
/opt/gitlab/embedded/service/gem/ruby/2.1.0/gems/gitlab_git-7.2.20/lib/gitlab_git/encoding_helper.rb
/opt/gitlab/embedded/service/gem/ruby/2.1.0/gems/gitlab-grit-2.7.3/lib/grit_ext.rb

В последней версии те же грабли.

По вашему методу нужно править вот файлы:
/opt/gitlab/embedded/service/gem/ruby/2.1.0/gems/gitlab_git-7.0.0.rc14/lib/gitlab_git/encoding_helper.rb

/opt/gitlab/embedded/service/gem/ruby/2.1.0/gems/gitlab-grit-2.6.12/lib/grit_ext.rb

Видимо фикса не видать нам как своих ушей. И будем накладывать патч с выходом каждой версии. 🙁

Добавить комментарий