Cube のプロジェクト構成およびビルド&テスト方法

現在、cube-soft@GitHub には CubePDFCubeICE 等の実装コードを始めとして様々なリポジトリが存在します。この記事では、これらのリポジトリを修正する際の基本的な情報について記載します。

ディレクトリ構成

<WorkDirectory>
  + Cube.Core
  + Cube.FileSystem
  + Cube.FileSystem.SevenZip
  + Cube.Forms
  + Cube.Images
  + Cube.Net
  + Cube.Pdf
  + Cube.Xui
  + packages
  + resources
    + native
      + x86
      + x64

Cube プロジェクトの各リポジトリは、ローカル環境において上記のように配置されている事を想定しています。ただし、Cube.* ディレクトリに関しては異なるリポジトリ間では NuGet パッケージ経由で参照設定を行っているので、必要な(修正したい)リポジトリのみが配置されていれば問題ありません。

packages ディレクトリには NuGet で取得したパッケージ、resources ディレクトリにはそれ以外のライブラリを配置します。packages ディレクトリに関しては、nuget コマンドまたは Visual Studio 経由でパッケージの復元を実行すれば自動的に配置されるため、特に気にする必要はありません。resources ディレクトリには、native と言うサブディレクトリを作成し、そこにアンマネージド・ライブラリを x86/x64 別に配置します。現在、Cube プロジェクトで利用しているアンマネージド・ライブラリは以下の 2 種類です。

リポジトリ ライブラリ ディレクト
Cube.Pdf Ghostscript gs
Cube.FileSystem.SevenZip 7-Zip 7z

これらのライブラリは必ずしもここに配置する必要はありませんが(最終的な実行ディレクトリに存在しておけば良い)、後述する Rakefile との兼ね合い、および Continuous Integration (CI) 環境である AppVeyor とディレクトリ配置を統一する意味で、このディレクトリ構成としています。尚、Cube プロジェクトで使用しているアンマネージド・ライブラリは cube-soft@GitHub 内の各種 GitHub Releases からもダウンロード可能です。詳細については、下記を参照下さい。

Git ブランチ構成

Cube プロジェクトには、master, stable, net35 と言う 3 種類のブランチが存在します。この中で、特に何もしなくてもビルド可能なブランチは stable ブランチとなります。そのため、通常は stable ブランチを起点にすると楽です。net35 ブランチは、stable ブランチと同等の内容を .NET Framework 3.5 ターゲットでビルド可能にしたものなので、必要な場合以外は無視して構いません。

master ブランチは、開発中のものまで含めた最新の状態であるため、NuGet でまだ公開されていないバージョンを参照している可能性があります。master ブランチでビルドする場合、該当リポジトリに存在する AppVeyor.yml 等を参考にしながら、未公開の NuGet パッケージも取得可能なように設定して下さい。また、参照されている NuGet パッケージ自体にも、該当バージョンが NuGet パッケージとして公開されるまでに度々、修正が行われます。ビルドに失敗する等の問題が発生した場合は、packages ディレクトリにある各種 Cube.* ディレクトリを削除してみて下さい。

ビルド&テスト方法

ビルドは Visual Studio を起動して「ビルド」メニューを選択すれば、特に難しい点はないかと思います。テストフレームワークとして NUnit を使用しているので、Visual Studio 上でユニットテストを実行する場合は拡張機能から NUnit3 Test Adapter を選択してインストールして下さい。

コマンドライン上からの各種実行に関しては Rakefile に記述しているため、Ruby および Rake の実行環境が必要となります。Rakefile に記述しているタスクは clean, build, copy, pack, test の 6 種類で(copy は存在しない場合もある)、デフォルトでは test 以外のタスクが順に実行されます。clean は対象オブジェクトを消去し、build はその名の通りビルドを実行、pack は NuGet パッケージの作成用タスクです。尚、これらのタスク実行中には stable ブランチと net35 ブランチを何度か切り替えるので注意して下さい。

copy タスクは、必要なアンマネージド・ライブラリを bin 下の各ディレクトリにコピーします。この時、コピー元のファイル群は resources/native に存在する事を想定しているので、それらのファイルは該当ディレクトリに配置して下さい。また、Architecture (x86, x64, AnyCPU), Configuration (Debug, Release), Branch (stable, net35) 毎に出力ディレクトリが異なるので、最終的に 12 種類のディレクトリにコピーされます。

test タスクは、現在のブランチを対象にして、ビルドと NUnit によるテストを実行します。これ以外のタスクは、現在のブランチが何かに関わらず stable, net35 の 2 種類のブランチを対象とするので、このタスクのみ特殊となります。尚、ユニットテストは、ローカル環境における開発中は Visual StudioGUI で確認する事が多いので、現状では net35 ブランチのテスト結果確認用と言う意味合いが強くなっています(Visual Studio の該当機能が .NET Framework 3.5 非対応となったため)。

その他、AppVeyor における CI 実行内容はリポジトリ毎に存在する AppVeyor.yml に記述しているので、こちらも何かの理解に役立つかもしれません。

2018 年の振り返り

2018 年も残り僅かとなりました。この記事では、私の 1 年間の活動を振り返ります。

GitHub Activity

GitHub

まず、GitHub Activity に目を向けると、2018 年は 2,321 コミット (contributions) と言う結果になりました。GitHub の Activity を意識し始め ておよそ 2 年が経過しましたが、特別な理由がない限り毎日コミットし続けると言う目標を今年も概ね達成できた事は何よりでした。

レコーディング・ダイエットのような形で自らのコミットを記録し続けて気付いた点として、平均的に見た場合、1 日 10 コミットは想像以上に大変 と言うものが挙げられます。もちろん、1 コミット当たりの修正量によって総作業量は変わってきますが、この事実は自分がそれまでに漠然と想像していた量よりも随分と少ないと言うのが率直な感想です。何らかのソフトウェアを開発する際にも、この事実を念頭に置きながら大雑把に見積もる事で、当初想定する期間と現実とのギャップが埋まってきたのは良い副産物であったように感じます。

リポジトリおよびコードの整理

2018 年は、2017 年の中頃から始まった これまで CubeSoft として公開してきたソフトウェアに対する開発サイクルの再構築 を推し進めた年となりましたが、その中の一つに、リポジトリおよびコードの整理があります。CubeSoft としては現在、下記の 8 個をアクティブな公開リポジトリとして管理しています。非公開リポジトリや fork したリポジトリを含めるともう少し存在しますが、ここ 2 年は多くの時間をこれらのリポジトリに注いでいます。

コードの整理と言う観点で見ると、2018 年は コメントの一部を英語で書くように方針転換した 事が大きな特徴の一つです。私自身は「下手な英語よりは、まともな日本語の方がマシ」と言う価値観であるため、これまではコードのコメントも日本語で記述していました。しかし、Visual Studio を始めとした最近の開発環境には、JavadocXML Documentation などの構造化されたコメントを解析してポップアップ表示する機能が標準搭載される事も珍しくなくなってきました。

XML Documentation

このため、上記のようなコメントを日本語で記述した場合、該当コードを利用するユーザの開発環境では、そのユーザの言語設定に関わらず日本語が表示される事となります。前述したリポジトリもその多くは利用可能なライブラリとして NuGet に登録しており、その結果、少しずつですが海外のユーザにも試して頂けているようです。このような状況を鑑みると日本語のコメントが表示されてしまうのは好ましくないと思い、方針の転換を決定しました。

方針転換に際しては当初、英語と日本語、両方のコメントを管理する事も選択肢として検討しました。しかし、XML Documentation では複数言語のコメントを管理するための良い仕組みが見当たらなかった事、管理するコメント量が増えるにつれて嘘のコメントの危険性が増加する事、そして何より、私自身、まったく同じコメントが複数言語で記述されたソースコードなど見たくなかった事などの理由で、日本語のコメントを捨てる事にしました。2018 年現在、既存のコードには大量の日本語コメントが残ってはいますが、この辺りは少しずつ修正していこうと思います。

CI の徹底およびテストカバレッジの可視化

Codecov

ユニットテストで振り返るプログラマとしての自分史 でも触れましたが、開発サイクルを再構築して大きく変わった点は AppVeyor を利用した継続的インテグレーション (CI: Continuous Integration) の徹底、および Codecov によるテストカバレッジの可視化です。

テストカバレッジの可視化に関しては、長年、自分の中にも「テストカバレッジの数値を気にするようになると、数値を上げるためだけのユニットテストを記述するようになるのではないか?」という不安が常にありました。そして実際、数値を上げる以外の意義を感じられないユニットテストを数多く記述し、これに何の意味があるのか……と言う感情を抱く事も何度もありました。

しかし、面白い事に 2 年ほどリファクタリングや修正を続けていると、数値を上げる以外に意義を感じられないユニットテストに何度も救われる事となりました。例えば、View に表示するメニューやメッセージの文字列 などは、記述時は「定義ファイルに決め打ちで記述するのだし、テストするまでもなく明白」のような気がしていました。しかし、ある時、何らかの修正時にうっかり定義ファイルの記述位置がずれてしまい、さらに不幸な事に、ビルド時にも実行時にもエラーが発生しなかった事がありました。このケースに関しては、ユニットテストがなければ表示内容が異なっている事に、しばらく気付く事ができなかったのではないかと言う気がします。

テストカバレッジの数値を上げるためだけの近視眼的なテストコードを記述する事によって、それよりも重要なテストコードを見逃すのではないかと言う不安は依然としてあります。ただ最近は、ある程度は仕方がないと割り切り、以下のような指針で実装およびテストコードの記述を行っています。

  1. 初期リリースまでは、取り合えずテストカバレッジの数値(80%~95% 程度)を指標としてテストコードを記述する。この結果、初期リリース時点では、正常ケースおよび容易に予想可能な異常ケースのテストに留まる事が多い。
  2. リリース後に何らかの不都合が発覚した場合、必ず最初に該当の不都合が再現するテストコードを記述する。そして、テストを実行してレッド・シグナルを確認する。
  3. 該当部分の実装コードを修正し、テストを実行してグリーン・シグナルを確認する。

このサイクルによって、完全ではないにしても「少しずつだが、良くなってはいる」事を実感できるのは、テストコードを含めた保守を続けていく、あるいは習慣化する上でプラスに働いていると思います。

CubePDF シリーズの大改修

ソフトウェア別で見ると、2018 年は CubeSoft において最も多くの人達に利用されている CubePDF を始め、CubePDF シリーズの開発を継続的に続けていけるよう、様々な面において保留となっていた事柄に取り組めた 1 年であり、その意味でも充実度は高かったように思います。

具体的に挙げるとすると、GUI の英語化は大きな特徴の一つでしょうか。特に CubePDF に関しては、全て日本語表示であった頃から海外ユーザが存在していたようで、そう言った事も含めて複数言語の View を開発するためのパターンが自分の中で確立できたのは良かったと思います。

また、CubePDF には ユーザーズマニュアル と言う PDF を同梱していますが、この基となるドキュメントを markdown 形式で書き直す事でバージョン管理に含められるようになったのも、個人的には満足した出来事です。

CubePDF に含まれる Ghostscript を手動で更新する方法

先日、Ghostscript が 9.26 にバージョンアップしました。リリースノートによると Ghostscript 9.26 では再び、セキュリティ問題に関する修正が実施されているようです。CubePDF も、近日中に Ghostscript のバージョンアップを含めた最新版をリリースする予定ですが、この記事では CubePDF に含まれる Ghostscript を手動で更新する方法について記載します。

まず、CubePDF のバージョンを確認して下さい。CubePDF のバージョンは、適当なものを CubePDF プリンタで印刷し、表示されるメイン画面の「その他」タブで確認する事ができます。

CubePDF バージョン情報

該当項目が存在しない場合は、CubePDF のバージョンが古いため最新版にアップデートして下さい。CubePDF は 1.0.0RC12 にてフォルダ構成等を変更しているので、バージョンが 1.0.0RC12 未満(1.0.0RC11 や 0.9.9β など)の場合は、必ず最新版に更新するようお願いします。バージョンが問題なければ、その右隣に記述されている文字列(x86 または x64)を覚えておいて下さい。

次に、Releases - Cube.Pdf - GitHub へ移動します。ここで、先ほどのバージョン表示画面で確認した x86/x64 に対応する Ghostscript の最新版 Zip ファイル(例えば、gs-9.26-x86.zip など)をダウンロードして下さい。

Ghostscript の差し替え方法

ダウンロード終了後、解凍・展開したフォルダにある gsdll32.dll および各種フォルダを全て CubePDF のインストールフォルダ(初期設定では C:\Program Files\CubePDF)にコピーして差し換えると、手動による Ghostscript の更新作業は完了です。