M12i.

学術書・マンガ・アニメ・映画の消費活動とプログラミングについて

ディプロ2016/9「そしてマネは物議をかもした」

ル・モンド・ディプロマティークにP・ブルデューの草稿が載っていました。

そしてマネは物議をかもした」。エドゥアール・マネが19世紀画壇で行った革命は、結局どのような状況下で(こそ)生み出され、どのような状況下で(こそ)受容・消費されたのか。

日本語版*1を読んでいて何だか釈然としない気がしていたのでちらと原文*2を見たらば、日本語版はだいぶ中略をしていたようです。

日本語版の結び「そして、わたしが強調したいのはこの最後の点についてです。」のあとに、原文ではおおよそ「なぜならこの問題は、美術史家、文学史家、法律史家、人文に関するすべての歴史家に通底するものだからです。」という一文と引き続きの数パラが存在していました。

"…Et, d’autre part, sur le fait que cette esthétique de la réaction, ou de l’effet, doit être une esthétique de la disposition et non pas de l’intention. Et c’est sur ce dernier point que je voudrais insister, parce que c’est un problème tout à fait général qui se pose aux historiens de l’art, de la littérature, du droit, bref, aux historiens de toutes les œuvres humaines."

「…そして他方では、〔マネの絵画作品に対する〕反響あるいは効果に関する美学は〔生産者と消費者の〕『意図』の美学ではなく、〔彼らの〕『性向』の美学でなければならないという事実に基づいています。そして、わたしが強調したいのはこの最後の点についてです。なぜならこの問題は、美術史家、文学史家、法律史家、人文に関するすべての歴史家に通底するものだからです。」

*1:日本語版のURLはこちら: http://www.diplo.jp/articles16/1609-MDVmanet.html

*2:原文のURLはこちら: http://www.monde-diplomatique.fr/mav/148/ ただし2017/01/31現在サイトの会員でないと閲覧できなくなっている模様。

Jenkins 2.xのPipelineとは結局なんなのか?

ここ数週間、職場でxUnitに関するハンズオンを開催していて、その関連の話題としてJenkins 2.0で導入されたPipeline機能についても調べていました。従来サードパーティプラグインとして存在していたPipelineがこのバージョン(2016年4月リリース)から本体にデフォルトで備わったかたちで提供されるようになったのだそうです。

誤った類推

ただこのPipeline、「使い方」を示す例はまま見かけるのですが、「Pipelineとは結局なんなのか?」「何がどうPipelineなのか?」「何をするためのPipelineなのか?」「何がメリットなのか?」を説明する記事は日本語記事では見かけませんでした。そういうわけで「Pipeline」というワードから私が想像したのはデザインパターンPipes and Filtersでした。

もし仮にそれが正しいとすれば(事実は正しくないのですが)、UNIX/LinuxのShellでお馴染みのパイプやNode.jsの標準ライブラリが提供しているStream(Gulpのgulpfile.jsで主役を果たすアレ)と、JenkinsのPipelineは親戚関係ということになります。そしてJenkinsのPipelineを定義するためのDSLの構文はどうみてもこのPipes and Filtersパターンに該当するようには見えません(例えばGulpとGruntの比較でいえば断然後者に似ています)。

もちろんこの類推は正しくなくて、答えはJenkinsの公式サイトのリファレンスに示されていました*1

疑問への答え

まず第一に重要な点、それは「PipelineはPipes and Filters PatternのそれではなくContinuous Delivery Pipeline(CDP)のそれである」ということです。

CDはCIを拡張した概念で、ざっくりいうと、製品の本番環境デプロイをも射程に入れたオートメーション化により、品質の保証、生産性の向上、そしてスピーディなサービスインを目指す考え方・実践(*-ism)のようです*2

化石燃料や水道などと同じく、ソフトウェア(やその新機能)も淀みない流れのように、速やかに・恒常的に顧客のもとに送り届けられるべきだ」ということらしいのです。

その上で第二に重要な点、Jenkins2.xのPipelineは以下の2点を実現するための機能だということです:

1. CDを実現する基盤を提供してくれる

  • ワークスペースの用意、SCMからのコードのチェックアウト、ビルド、テスト、メトリクス収集、パッケージング、デプロイといったステップを自動化してパイプラインを構築する基盤を提供。
  • でも、これだけなら従来からできた(フリースタイルジョブを使って画面から各ステップを担当するジョブを登録すればよかった)。

2. CDをスクリプトで記述できるようにしてくれる

  • Groovyで実装されたDSLを使って、各ステップをスクリプトで(≠画面で)定義することが出来る。
  • そしてこれこそが重要なところ。スクリプトであることでそれ自体を容易にバージョン管理できるし、柔軟(≒複雑)なステップから構成されるPipelineを構築できる。

CDの各ステップの連なり(≒Pipeline)をスクリプトで作成できること。こう書いてしまえばどうということもないものですが、これこそが核心となる事項です。

Web上の日本語記事のほとんどが「Pipeline機能はCDを実現するためのものであること」や「画面でなくコードで記述するのが重要であること」という、「そもそもの前提となる事項」についてまったく言及していません。ことほどさように「CD/CIなんて業界的には当たり前」ということかもしれないが・・・。

*1:右のURLを参照のこと: https://jenkins.io/doc/book/pipeline/

*2:CDもしくはCDPについての解説は右のURLなどを参照のこと:https://devops.com/continuous-delivery-pipeline/

Sphinxの拡張機能"sphinx-csharp"に機能を追加

Sphinx拡張機能"sphinx-csharp"に機能を追加したときのメモ。

やりたかったこと

pipを通じてインストールできるSphinx拡張機能"sphinx-csharp"に機能を追加したい。より具体的に言うと、この拡張機能が提供してくれるC#言語用のドメイン(ディレクティブとロールのセット*1)を拡張して、以下の3つをできるようにしたい:

  • メソッドのパラメータに修飾子(ref, out, params)を指定
  • メソッドの修飾子を複数指定
  • クラスのメンバーとしてインデクサーを記述(ディレクティブは.. indexer:: ...、ロールは:idxr:`...`

やったこと

#1. PyPIで調べる

PyPIサイトの"sphinx-csharp"のパッケージ・ページ(ここ)を参照。プロジェクトがGitHub上のリポジトリホスティングされれいることを確認。

f:id:m12i:20170103214529p:plain

#2. GitHubでForkする

まずはこのページに記載されているGitHub上のリポジトリここ)からプロジェクトをFork。私個人のリポジトリとしてPushできるようにしました(Fork先はここ)。

#3. ローカルにクローンを作成

Forkしたリポジトリを元にしてローカルにクローンを作成しました:

$ git clone https://github.com/mizukyf/sphinx-csharp.git

#4. Pythonコードを加筆修正

プロジェクトを構成するPythonスクリプト・ファイルをAtomテキスト・エディタでオープンして、色々変更を行いました。変更内容を知りたい場合は前述のFork後のリポジトリのCommit内容を確認してみてください(コミット一覧)。

#5. Sphinxプロジェクトで動作確認

Pythonコードの修正後、そもそもの動機の根源となっていたSphinxプロジェクト(もちろんC#で実装されたライブラリのAPIリファレンスを執筆しているプロジェクト)の設定ファイルconf.pyを修正:

import os
import sys
sys.path.append(os.path.abspath('/path/to/sphinx-csharp'))

クローンした"sphinx-csharp"が置かれているディレクトリをモジュール検索パスに追加します。生々しいですが、私的な用途なのと当面は動作確認も兼ねて使うことになるのでまあいいでしょう。

上記設定をした上でSphinxプロジェクトのreStructuredTextに追加したマークアップ(ディレクティブとロール)を利用したコードを記述。そしてビルドを行いました。

ふむ、まあまあかな?

構文サンプル

拡張されたメソッドおよびインデクサーのためのマークアップのサンプルを掲載しておきます。リポジトリにもコミットされている"/test/index.rst"を大幅に端折ったものです:

.. default-domain:: csharp

.. namespace:: MyNamespace

.. class:: MyClass

   This is a class with methods and properties.

   Here are some references to it's methods and properties:

       * :meth:`MyClass.MyMethod`
       * :meth:`MyMethod`
       * :prop:`MyClass.MyProperty`
       * :prop:`MyProperty`

   (・・・中略・・・)

   .. method:: int MyMethodHasParamModifiers(ref int arg0, params int[] arg1)

      A method with a parameter modifier.

   .. method:: public static MyMethodHasMultiModifiers()

      A method with multiple method modifiers.

   .. property:: string MyProperty { get; set; }

      A read/write property.

      (・・・中略・・・)

   .. indexer:: string this[int i] { get; set; }

   .. indexer:: string this[int i] { get; }

   .. indexer:: virtual string this[int i] { get; set; }

   .. indexer:: string this[int i, MyClass j] { get; set; }

      (・・・中略・・・)

Indexer ref :idxr:`MyClass.this[]`

*1:SphinxにはAPIを構成するクラスやそのメンバーをディレクティブ(Directive)でマークアップして、同じreStructuredTextファイルや別のファイルの中の対応するロール(Role)でマークアップした箇所から参照できるようにする機能があります。これらのディレクティブとロールはドメイン(Domain)という一種の名前空間を持っており、Python言語やGo言語などそれぞれのプログラミング言語ごとにその名を関したドメイン拡張機能(Extension)として配布されています。