非公式日本語版 GitHub Desktopの製造について

## はじめに
GitHub は強力なコラボレーションサービスですが、GUIツール、特にLinuxに関しては、日本語環境が整備されていない状態でした。

　ただ GitHub Desktop はソースが公開されていたことから2022年秋から会社業務とは関係なく、業務時間外に日本語化に手を付けて、2022年9月末には一応の成果として完成し、本家issueにEnhancementとして提案させていただきました。
　ただ、本家からは他に進めないといけない議題があるということで了承し、マルチランゲージプラットホームは僕のリポジトリで継続してメンテする形となっています。

　今まではソースのみの提供でしたが3.3.7 betaからWindows版、インテルMacOS版、Linux AppImage版のインストーラーの配布を始めている状態です。

## とにかく使いたい
説明はいいからバイナリーを使いたいという方はこちら。
リンク先wikiに配布バイナリーのダウンロードリンクが記載されています。
　僕の方で配布を制限することはしませんが、会社や学校に導入する場合は本家およびLinux版(shiftkeyさん作)の GitHub Desktop のインストールが許可されていたとしても、コミュニティビルド版の使用が大丈夫なのか確認は取ってください。

https://github.com/yasuking0304/desktop/wiki

## 日本語化の適用範囲
普通であれば、GUI部分のみが日本語化できれば目的は達成されるのですが、本来の GitHub Desktop は強力なコラボレーションツールであり、自身のissueレポートに関しても日本語化が必要だと思われました。

　そこで、少なくとも日本語issueに関してはLinux版を含めて僕のリポジトリに誘導するようにメニューからのリンクも変更し、.github/ISSUE_TEMPLATE の質問テンプレートに関しても日本語化を行い英語と日本語で説明するようにしています。

 また、Windows/MacOS版とshiftkeyさん作のLinux版のどちらもユーザーガイドのリンク先は日本語にしています。
![Screenshot_20240121_094215](https://github.com/yasuking0304/SetEnv-Lang-MacOS/assets/111163564/d48db2c4-b75e-42ba-b18e-a397bb06bbc3)

## GUIの日本語化の手法について
i18nextを使用しています。GitHub Desktop はElectronを使用している関係でCLI部分とUI部分のどちらも日本語化が必要で、ひとつのClassファイルとJsonファイルをCLIとUIから参照するようにしています。

追加したい場合、下記のような手順で翻訳プラットフォームを追加します。

### VSCode で対象ファイルを探す

一番手っ取り早いのは横断検索で「`__DARWIN__`」で翻訳非対応ファイルを探す

![WS000013](https://user-images.githubusercontent.com/111163564/191873139-dd68c45b-1e58-48c2-ac2c-b925d6c7f10e.JPG)

### 修正する

例として、``\app\src\main-process\show-uncaught-exception.ts``を修正する

![WS000014](https://user-images.githubusercontent.com/111163564/191873364-4f692597-f87f-48cc-beb8-231bc2dcf136.JPG)

ファイルの頭の方に``import { t } from 'i18next'`` を追加する

![WS000016](https://user-images.githubusercontent.com/111163564/191873675-1841a4c9-31c0-4eb5-a4ab-c0567776356d.JPG)

![WS000017](https://user-images.githubusercontent.com/111163564/191873769-c3f85bf0-c892-4765-bfe5-86443c5dab64.JPG)

↑の状態から翻訳対象をtつきに変更する↓

![WS000018](https://user-images.githubusercontent.com/111163564/191873805-bfdb0f2d-a5bc-4485-adc2-77d9793c0a9c.JPG)

このままでは、言語ファイルの管理がやりにくいので、第一パラメータに名前を付ける

言語ファイルの可読性を考えると、<ファイル名>.(ドット)<機能名>がよい

機能名は考えるのも疲れるので文言をスネークケースにして半角スペースはハイフンにするのが楽。他と被らないように。

ただ、短すぎると言語ファイルの管理がしにくく、あまりに長すぎるとソースが読みづらくなるので、ほどほどで。

元が ``__DARWIN__`` の場合、Mac側に ``-darwin`` を付けると見やすい。

改行位置はあとで機械的に行うので考えなくてよい。

![WS000019](https://user-images.githubusercontent.com/111163564/191874195-6fc6b217-fb17-4543-b838-23bfb2764919.JPG)

翻訳ファイルに追加するにはNPMスクリプトから``i18next-extract``を実行する

![WS000020](https://user-images.githubusercontent.com/111163564/191874494-bb238128-c3c1-4d5c-9fa3-06a58cd3537f.JPG)

出力に「[warning] Found same keys with different values」が表示された時はキーが競合しているので、修正する

![WS000021](https://user-images.githubusercontent.com/111163564/191874628-2c0dbd31-3a7b-4d25-9d86-8a54400df815.JPG)

こうなればOK

![WS000022](https://user-images.githubusercontent.com/111163564/191874776-6fdbd404-2230-410f-9d5d-831c40888490.JPG)

変更ファイルから日本語ファイルを選択して開く。

言語ファイルは、ファイル名でグループ化されているので(さきほどネーミングルールを指定したのはこのため)探すのは難しくないと思う。

![WS000023](https://user-images.githubusercontent.com/111163564/191874953-8ecf4e6a-9182-4e49-8455-a4ca049910f6.JPG)

まずは公式日本語ドキュメントを見て、該当する機能はその言葉を流用、そうでなければ英語や機能の知識があれば自分で、無理であれば Google翻訳なり Bing翻訳 なりを使えばよい。ただ、自分が読んで意味不明な文書を無理に機械翻訳する必要はないと思う。

日本語以外の人には従来通り英語のままで表示される（そのうち有志が頑張って翻訳してくれる）。

ただし表記ゆれに関しては公式のGitHub ユーザーガイドの記述に合わせるのがよいと思われる。例えば以下のキーワード。

| 適切なキーワード | あまり適切ではないキーワード |
|:---:|:--:|
|ブラウザー|ブラウザ|
|ユーザー|ユーザ|
|ディレクトリ|ディレクトリー|
|リポジトリ|リポジトリー|
|上位リポジトリ|親リポジトリ|
|無料アカウント|無料のアカウント|

### 【注意】「dangerouslySetInnerHTML」は絶対に使わないで

このソースは遠い将来、上位リポジトリ（本家）に取り込まれることを前提に製造しているため、セキュリティリスクが伴うコードは混入させないようにしています。

それでもある程度の言語の揺れを吸収したい場合の代替策として、タグの前後でメッセージを分割してconst値をどちらでも表示できるような仕組みにしておくのがよいです。

【例】
app\src\ui\banners\cherry-pick-undone.tsx
```TypeScript
  public render() {
    const { countCherryPicked, targetBranchName, onDismissed } = this.props
    const pluralized = countCherryPicked === 1 ? 'commit' : 'commits'
    return (
      <SuccessBanner timeout={5000} onDismissed={onDismissed}>
        Cherry-pick undone. Successfully removed the {countCherryPicked}
        {' copied '}
        {pluralized} from <strong>{targetBranchName}</strong>.
      </SuccessBanner>
    )
  }
```
は、このように変換して、タグの前でも後ろでも表示できる仕組みにしています。

```TypeScript
  public render() {
    const { countCherryPicked, targetBranchName, onDismissed } = this.props
    const pluralized =
      countCherryPicked === 1
        ? t('cherry-pick-undone.one-commit', 'commit')
        : t('cherry-pick-undone.multiple-commits', 'commits')
    return (
      <SuccessBanner timeout={5000} onDismissed={onDismissed}>
        {t(
          'cherry-pick-undone.cherry-pick-undone-1',
          `Cherry-pick undone. Successfully removed the {{0}}
          copied {{1}} from `,
          { 0: countCherryPicked, 1: pluralized }
        )}
        <strong>{targetBranchName}</strong>
        {t('cherry-pick-undone.cherry-pick-undone-2', `.`, {
          0: countCherryPicked,
          1: pluralized,
        })}
      </SuccessBanner>
    )
  }
```
ここで、日本語は単数と複数の観念がほぼないため、const値で翻訳された「コミット」を使わずに翻訳メッセージ側に直書きして``{{1}}``を翻訳メッセージに記載しないのは一向に構いません。
```JSON
  "cherry-pick-undone": {
    "cherry-pick-undone-1": "チェリーピックを元に戻します。コピーされた {{0}}個のコミットを ",
    "cherry-pick-undone-2": " から削除しました。",
    "multiple-commits": "コミット",
    "one-commit": "コミット"
  },
```
## 周辺ツールについて
### MacOS向け
MacOS向けにGUIアプリを作成してFinderにインストールした場合、環境変数 LANG の値が取得できなくて困ったことがおきます。
　具体的には画面は日本語化されるのに、メニューだけは英語のままとなってしまいます。

　これはインストールしたアプリの環境変数は lanchctl setenv <key> <value>で登録したものを使用するためです。ただ、lanchctl setenvでは再起動で値はクリアされてしまいます。

　このためplistファイルを生成して、launchdサービスに登録するshellを用意し、インストーラーに同梱するようにしています。
　このツールに関してはPublic Domainで公開しています。
 
 https://github.com/yasuking0304/SetEnv-Lang-MacOS

### Linux向け
GitHub Desktop のプロジェクトにはLinux向けのpackageする手段が用意されていません。
　さすがに各自で.debなり.rpmなりを作成してくださいというわけにもいかないので、pkg2appimage を使って AppImageファイルを作成するためのyamlファイルを生成する機能を追加しています。この機能はいまのところlinuxブランチだけ導入しています。
　pkg2appimage使用や ローカルファイルを使ったAppImageファイル作成はドキュメントもあまりないのですが敷居がそれほど高くはありませんので、これを期にチャレンジされてみてはどうでしょう。

## 既知の問題(Linux版を除く)
【問題】
自分でソースから独自ビルドしたアプリで、設定画面→ダイアログからサインインしてブラウザが開いた後、応答がない。ということが起きる場合があります。

【原因】
ベータ版でビルドしたアプリは、GitHubには「GitHub Desktop」ではなく「The GitHub Desktop Development App」として認識されるためです。

具体的には自分のGitHubページの
Settings → 左ペインの「Integrations」下にある Applications → 「Authorized OAuth Apps」タブで確認できます。

build:prodでビルドしても、 app -> package.json -> vesion に``test``の文字が含まれていたり、未知のバージョンの場合、GitHubサーバーにはDevelopmentで認識されます。
![cap_2023_12_31](https://github.com/desktop/desktop/assets/111163564/5ad9a64f-e643-4114-965c-828c8f67948a)

この場合、headerは ``x-github-desktop-auth`` ではなく ``x-github-desktop-dev-auth`` で応答しないといけません。

これは昔からGitHub Desktopをコミュニティビルドする人には避けて通れない問題で本家のissueでも説明済みですが、自前でビルドしたい場合は覚えておいてください。

https://github.com/desktop/desktop/issues/11410#issuecomment-1872924345

以上になります。