LoginSignup
8
2

More than 3 years have passed since last update.

素敵なライブラリをSatyrographosで配布しよう!

Last updated at Posted at 2019-12-12

この記事は SATySFi Advent Calendar 2019 12日目の記事です。前日は @amaoto017 さんの『SATySFi上で構文定義可能なシンタックスハイライト(の宣伝)』です。次日はしょうだいさんです。

用語

本記事では、以下の用語を使用します。

定義
SATySFi パッケージ packages/ 以下に置かれた *.satyh ファイルや *.satyg ファイル等。
ライブラリ・Satyrographos ライブラリ SATySFi パッケージやフォントファイル等を纏めた配布物。
OPAM パッケージ OPAM によって管理される配布物の単位。ライブラリに相当。

OPAM パッケージと SATySFi パッケージは名前が紛らわしいので気を付けて下さい。

新しいライブラリを書いたら

SATySFi 用のライブラリは専ら以下の要素で構成されます1

  • packages/ ディレクトリ以下に配置された *.satyh ファイルや*.satyg ファイル
  • fonts/ ディレクトリ以下に配置されたフォントファイル
  • md/ ディレクトリ以下に配置された *.satysfi-md
  • hash/fonts.satysfi-hash に追加されたエントリ
  • ライブラリのドキュメント

名前を決めましょう!

ライブラリを書いたら(書く前でも無問題なのですが)、名前を決めましょう。

名前の付け方

Satyrographos ライブラリ名は、今のところ以下の命名を推奨しています2satysfi- は付けないで下さい。

種類 備考
フォントライブラリ fons-* フォントファイルを含むライブラリ。例:fonts-theano
クラスライブラリ class-* document関数を含むライブラリ。例:class-exdesign
* その他。例:zrbase, base

ライブラリのインストール時に使われる OPAM パッケージ名は Satyrographos ライブラリ名に satysfi- を前置したものになります3。例えば、base という名のライブラリの OPAM パッケージ名は satysfi-base です。

名前の使われ方

Satyrographos ライブラリを利用する際にライブラリ名/を前置することになります4

例えば、math-constant ライブラリとして circular.satyh を配布する時、使用する側では math-constant/circular@require します。

circular.satyh
module Circular = struct
  let pi = 3.1415926535897932384626433832975
  let tau = 6.283185307179586476925286766559
end
abc.saty
@require: math-constant/circular

また、SATySFi フォント名には fonts-ライブラリ名: を前置して下さい。SATySFi-fonts-theano からの例を以下に示します。

{
  "fonts-theano:TheanoDidot":
    <"Single":{"src-dist":"fonts-theano/TheanoDidot-Regular.otf"}>,
  "fonts-theano:TheanoModern":
    <"Single":{"src-dist":"fonts-theano/TheanoModern-Regular.otf"}>,
  "fonts-theano:TheanoOldStyle":
    <"Single":{"src-dist":"fonts-theano/TheanoOldStyle-Regular.otf"}>
}

ビルドファイルを書きましょう!

現状、ライブラリ依存関係解決やネットワークからのデータ取得には OPAM を用いているために、Satyrographos 用のビルドファイルと OPAM パッケージファイルを両方書く必要があります……(解決する方法は模索中)。

Satyrographos 用のビルドファイル(Satyristes)

Satyrographos 用ビルドファイル Satyristes は S 式で記述します 5

概観するとこんな感じです。

Satyristes
(version 0.0.2) ; Satyrographos 0.0.2 系列向け

(library ; ライブラリ宣言
  (name "great-library") ; ライブラリ名
  (version "1.0") ; ライブラリバージョン
  (sources ; ファイル
    (;; ./interesting-font.ttf を dist/fonts/interesting-font.ttf に配置
     (font "interesting-font.ttf" "./interesting-font.ttf")
     ;; ./fonts.satysfi-hash を dist/hash/fonts.satysfi-hash に追記
     (hash "fonts.satysfi-hash" "./fonts.satysfi-hash")
     ;; ./def.satyh を dist/packages/great-library/abc/def.satyh に配置
     (package "abc/def.satyh" "./def.satyh")
     ;; ./ghi.satyh を dist/packages/great-library/ghi.satyh に配置
     (package "ghi.satyh" "./ghi.satyh")
     ;; ./grc.satysfi-hyph を dist/hyph/grc.satysfi-hyph に配置
     (file "hyph/grc.satysfi-hyph" "./grc.satysfi-hyph")))
  (opam "satysfi-great-library.opam") ; OPAMパッケージファイル
  (dependencies
    (;; fonts-theano ライブラリに依存(バージョン指定無し)
     (fonts-theano ())))
  (compatibility ; 互換性警告 
    (;; パッケージ <old-name> が <new-name> に変更されたことを使用者に警告
     (renamePackage "<new-name>" "<old-name>")
     ;; フォント <old-name> が <new-name> に変更されたことを使用者に警告
     (renameFont "<new-name>" "<old-name>"))))

OPAM パッケージファイル

OPAM パッケージファイルは satyrographos-ライブラリ名.opam という名前で作って下さい。

OPAMファイルは記法がややこしいので、作成・更新後に opam lint *.opam を実行し、エラー・警告が出ないか確認することを奨めます。

satysfi-great-library.opam
# satysfi-great-library.opam
opam-version: "2.0"
# OPAM パッケージ名
name: "satysfi-great-library" # satysfi- + ライブラリ名
version: "1.0"
synopsis: "A Great SATySFi Library"
description: """
Brilliant description comes here.
"""
maintainer: "Your name <email@example.com>"
authors: "Your name <email@example.com>"
license: "LGPL-3.0-or-later" # お好きなライセンスを
homepage: "<product home page>"
bug-reports: "<product issue tracker>"
dev-repo: "<repo url>"
depends: [
  "satysfi" {>= "0.0.5" & < "0.0.6"}
  "satyrographos" {>= "0.0.2.6" & < "0.0.3"}
  "satysfi-dist"

  # もし他のライブラリに依存している場合には、
  # OPAMパッケージ名とバージョン制約をここに記述して下さい
  "satysfi-fonts-theano" {>= "2.0+satysfi0.0.3+satyrograhos0.0.2"}
]
build: [ ]
install: [
  ["satyrographos" "opam" "install"
   "--name" "great-library" # ライブラリ名
   "--prefix" "%{prefix}%"
   "--script" "%{build}%/Satyristes"]
]

例:

ドキュメント

また、libraryDoc 節を Satyristes ファイルに追加(+対応するOPAM ファイルも追加)することで、ライブラリのドキュメントをビルドすることもできます。

実際の例を盛り込んだドキュメントを作ることを強く推奨します。ドキュメントライブラリは SATySFi 本体や他ライブラリ更新時にビルドが壊れないか検証されるため、破壊的変更の影響を受けづらくなります。

libraryDoc 節は将来的に library 節に統合されるかもしれません。

Satyristes(追加)
(libraryDoc ; ライブラリドキュメント宣言
  (name "great-library-doc") ; ライブラリ名 + "-doc"
  (version "1.0") ; ライブラリバージョン
  (workingDirectory "doc") ; ビルドコマンドを実行する為の作業ディレクトリ
  (build ; ビルドコマンド
    (;; make に引数 "-f" "build.make" を与えて起動
     (make "-f" "build.make")
     ;; SATySFiで処理
     (satysfi "great-library.saty" "-o" "great-library.pdf")))
  (sources ; ファイル
    ((doc "great-library.pdf" "doc/great-library.pdf")))
  (opam "satysfi-great-library-doc.opam") ; OPAMパッケージファイル
  (dependencies ; 依存関係
    ((great-library ())
     (exdesign ()))))

ビルドコマンドには (make 引数…)(satysfi 引数…) が使えます。依存関係に書かれているライブラリを自動で準備してから satysfi コマンドを実行します。

対応する OPAM パッケージファイルは以下のようになります。

great-library-doc.opam
opam-version: "2.0"
# 対応するライブラリ名 + "-doc"
name: "satysfi-great-library-doc"
version: "1.0"
synopsis: "Document of A Great SATySFi Package"
description: """
Brilliant description comes here.
"""
maintainer: "Your name <email@example.com>"
authors: "Your name <email@example.com>"
license: "LGPL-3.0-or-later"
homepage: "<product home page>"
bug-reports: "<product issue tracker>"
dev-repo: "<repo url>"
depends: [
  "satysfi" {>= "0.0.5" & < "0.0.6"}
  "satyrographos" {>= "0.0.2.6" & < "0.0.3"}

  # satysfi- + ライブラリ名
  "satysfi-great-library" {= "%{version}%"}

  # もし他のライブラリに依存している場合には、
  # OPAMパッケージ名とバージョン制約をここに記述して下さい
  "satysfi-exdesign"
]
build: [
  ["satyrographos" "opam" "build"
   "--name" "great-library-doc" # ライブラリ名 + -doc
   "--prefix" "%{prefix}%"
   "--script" "%{build}%/Satyristes"]
]
install: [
  ["satyrographos" "opam" "install"
   "--name" "great-library-doc" # ライブラリ名 + -doc
   "--prefix" "%{prefix}%"
   "--script" "%{build}%/Satyristes"]
]

ビルドしましょう!

Satyristes ファイルや OPAM ファイルを書き終えたらテストの時間です。
以下のコマンドで、現在のディレクトリをピン留め6してビルドしてみましょう。

成功例
$ opam pin add -v "file://$PWD"
Package satysfi-great-library does not exist, create as a NEW package? [Y/n] y
The following actions will be performed:
  - install satysfi-great-library 1.0*
Do you want to continue? [Y/n] y

<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><>
+ /home/<user>/.opam/opam-init/hooks/sandbox.sh "install" "satyrographos" "opam" "install" "-name" "great-library" "-prefix" "/home/<user>/.opam/4.09.0" "-script" "/home/<user>/.opam/4.09.0/.opam-switch/build/satysfi-great-library.1.0/Satyristes" (CWD=/home/<user>/.opam/4.09.0/.opam-switch/build/satysfi-great-library.1.0)
-> installed satysfi-great-library.1.0
Done.

以上のようなメッセージが出たら成功です!

失敗例としては以下のようなものがあります。

失敗例
$ opam pin add -v "file://$PWD"

...

#=== ERROR while installing satysfi-great-library.1.0 ================================#
# context     2.0.0 | linux/x86_64 | ocaml-base-compiler.4.09.0 | pinned(file:///home/<user>/Documents/Development/satysfi/packages/satysfi-lib)
# path        ~/.opam/4.09.0/.opam-switch/build/satysfi-great-library.0.0.1
# command     ~/.opam/opam-init/hooks/sandbox.sh install satyrographos opam install -name satysfi-great-library -prefix /home/<user>/.opam/4.09.0 -script /home/<user>/.opam/4.09.0/.opam-switch/build/satysfi-great-library.1.0/Satyristes
# exit-code   1
# env-file    ~/.opam/log/satysfi-base-472050-05296d.env
# output-file ~/.opam/log/satysfi-base-472050-05296d.out
### output ###
# Uncaught exception:
#   
#   (Failure "Build file does not contains library satysfi-great-library")
# 
# Raised at file "stdlib.ml", line 29, characters 17-33
# Called from file "src/command.ml", line 2817, characters 8-205
# Called from file "src/exn.ml", line 107, characters 6-10



<><> Error report <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
+- The following actions failed
| - install satysfi-great-library 1.0
+- 
+- The following changes have been performed
| - remove satysfi-great-library 1.0
+- 

The former state can be restored with:
    opam switch import "/home/<user>/.opam/4.09.0/.opam-switch/backup/state-20191212143911.export"
Or you can retry to install your package selection with:
    opam install --restore
'opam pin add file:///home/<user>/Documents/Development/satysfi/packages/satysfi-lib --verbose' failed.
zsh: exit 31    opam pin add "file://$PWD" --verbose

この場合は、satysfi-great-library.opaminstall: 節が以下のようになっていることから、satyrographos opam install -name satysfi-great-library -prefix …… -script …… が失敗していることが分かります。

satysfi-great-library.opam
build: [
  ["satyrographos" "opam" "build"
   "--name" "satysfi-great-library" # <- satysfi- は要らない
   "--prefix" "%{prefix}%"
   "--script" "%{build}%/Satyristes"]
]

Satyrographos のエラーメッセージ等は改善していきたいので、何かありましたらご報告下さい。

リリースしましょう!

GitHub で開発していることを仮定します。GitHub そのものの使い方の解説は他に譲ります。

GitHub にてリリースを行う際には、

  1. git tag -a <バージョン> でタグ付けをして、
  2. git push origin <バージョン> で push する

ことになるかと思います。

一旦 GitHub でリリースしてしまえば、以下のコマンドでライブラリを satyrographos-repo にプルリクエストを送ることができます。

$ cd OPAMファイルのある場所
$ opam publish --repo=na4zagin3/satyrographos-repo

送ったプルリクエストが受け入れられれば公開完了です。お疲れさまでした!

Satyrographos 最後の実装予定機能

ところで

というわけで(?)、Satyrographos 最後の機能はネイティブなパッケージマネージャ形式への移行支援であることは決定事項です。

それまではSATySFi用パッケージマネージャーのベースラインかつ実験場として開発を頑張っていこうと思っています。


  1. 他のパターンがあったら教えて下さい 

  2. 未定ですが、*.satysfi-md を配布するライブラリには md- を付けてもらった方が分かりやすいかもしれませんね? 

  3. OPAM パッケージ名に satysfi- を前置するやり方は、Coq.io(なら)ったものです。 

  4. Satyrographos 0.0.2 から ライブラリ名/ の前置が要求されます。これは、将来導入予定パッケージシステムを模擬するものです。(na4zagin3/satyrographos#24) 

  5. パーズを簡単にするため S 式にしてみたのですが、反応を見る感じ YAML の方がウケが良さそうなので切替えようかと思っています 

  6. ローカルの OPAM パッケージリストに仮登録 

8
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
2