RailsのStatsタスクに調査対象ディレクトリを追加してみる
どうもです。rake stats
コマンドを使っていますか?これは一言で言えばプロジェクトの大まかな統計情報を取るためのコマンドです。リファクタリングすべきかどうか、テストコードを書くべきかどうかをざっくり判断したいときに使ったりします
$ rake stats +----------------------+-------+-------+---------+---------+-----+-------+ | Name | Lines | LOC | Classes | Methods | M/C | LOC/M | +----------------------+-------+-------+---------+---------+-----+-------+ | Controllers | xxx | xxx | xxx | xxx | xxx | xxx | | Helpers | xxx | xxx | 0 | xxx | xxx | xxx | | Models | xxx | xxx | xxx | xxx | xxx | xxx | | Libraries | xxx | xxx | xxx | xxx | xxx | xxx | | Integration tests | 0 | 0 | 0 | 0 | 0 | 0 | | Functional tests | xxx | xxx | xxx | 0 | 0 | 0 | | Unit tests | xxx | xxx | xxx | xxx | 0 | xxx | | Cucumber features | xxx | xxx | 0 | xxx | 0 | xxx | +----------------------+-------+-------+---------+---------+-----+-------+ | Total | xxx | xxx | xxx | xxx | xxx | xxx | +----------------------+-------+-------+---------+---------+-----+-------+ Code LOC: xxx Test LOC: xxx Code to Test Ratio: xxx:xxx
※xxxは実際の数字をぼかしているだけです
各項目の具体的な意味は上記を参考に・・
ただ、上記で対象となっているディレクトリはデフォルトのものとGemをインストールしたときに追加されたものしか含まれていません
独自に作ったlib/request/
以下を対象としたい場合などに困りますね
調査対象を独自に追加する
具体的な実装はrails/code_statistics.rbに、拡張方法はRSpecのコードなどを見れば大体わかります(内容は端折ります) 調査対象は::STATS_DIRECTORIESという2次元配列に
> ::STATS_DIRECTORIES => [["Controllers", "xxx/app/controllers"], 略 ["Cucumber features", "features"]]
みたいな感じに表示名とパスが入っているので単純に対象を追加してやればいいです
例えば、lib/tasks/hoge_huga.rb
ファイルに以下のような記述をします
namespace :hoge_huga do task :statsetup do require 'rails/code_statistics' ::STATS_DIRECTORIES << %w(Custom\ Requests lib/requests) if File.exist?('lib/requests') end end task stats: 'hoge_huga:statsetup'
こうすれば既存のstatsタスクが実行される前に必ずhoge_huga:statsetupタスクが実行されるので対象が追加されます
実行結果は以下のとおり
$ rake stats +----------------------+-------+-------+---------+---------+-----+-------+ | Name | Lines | LOC | Classes | Methods | M/C | LOC/M | +----------------------+-------+-------+---------+---------+-----+-------+ | Controllers | xxx | xxx | xxx | xxx | xxx | xxx | | Helpers | xxx | xxx | 0 | xxx | xxx | xxx | | Models | xxx | xxx | xxx | xxx | xxx | xxx | | Libraries | xxx | xxx | xxx | xxx | xxx | xxx | | Integration tests | 0 | 0 | 0 | 0 | 0 | 0 | | Functional tests | xxx | xxx | xxx | 0 | 0 | 0 | | Unit tests | xxx | xxx | xxx | xxx | 0 | xxx | | Cucumber features | xxx | xxx | 0 | xxx | 0 | xxx | | Custom Requests | xxx | xxx | xxx | xxx | xxx | xxx | +----------------------+-------+-------+---------+---------+-----+-------+ | Total | xxx | xxx | xxx | xxx | xxx | xxx | +----------------------+-------+-------+---------+---------+-----+-------+ Code LOC: xxx Test LOC: xxx Code to Test Ratio: xxx:xxx
ちなみに対象がテストコードである場合、テスト系の項目に数値を反映させるために
::CodeStatistics::TEST_TYPESに表示名を追加する必要があります
namespace :hoge_huga do task :statsetup do require 'rails/code_statistics' ::STATS_DIRECTORIES << %w(Custom\ Requests lib/requests) if File.exist?('lib/requests') ::CodeStatistics::TEST_TYPES << "Custom Requests" if File.exist?('lib/requests') end end task stats: 'hoge_huga:statsetup'
まあ、これを追加する必要のある人は少ないと思いますが・・
参考
Mac上にGoのバージョン管理ツールgvmをインストールしてみた
追記(2017/04/19): MacOS Sierraだとコンパイルに使用するGo 1.4が動作しないため失敗するらしいです
公式のバイナリpkgならうまくいきます
Downloads - The Go Programming Language
仕事でGoを使う機会に巡り会えそうだったので、ちょっとフライング気味に勉強してみることにしました
となるとやはり初めはバージョン管理ツールの導入なのだが、Go界隈の流行りはどうなっているんだろう
調べる感じRubyとかほどバージョン管理ツールは使われていないのかな?情報が少ない印象を受けました
お馴染みの命名規則でgoenvとかgvmとかいったものがあるらしいですがGoogle トレンドを見る感じでは、gvmのほうが使われている印象を受けました(データ量が少ないけど・・)
https://www.google.co.jp/trends/explore?date=today%2012-m&geo=JP&q=goenv,gvm
同名のgoenvでこんなのもありましたが、こっちはプロジェクト作成ツールっぽい?(あとで見る)
という訳で一旦gvmを使うことに決定しました!
導入済みのanyenvは名前の通りgoenvしか使えないので一からインストールします
Macにgvmをインストールする
とりあえず先に依存ツールをすべてインストールします
xcode-select --install brew update brew install mercurial
本体のインストールは以下のコマンドです(zshの人は先頭の"bash"を"zsh"にしてください)
bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
もしzshを使用しているのに間違えてbashで実行してしまったら
"ERROR: Already installed!"
と表示されてインストールできなくなってしまいます
そのときは一旦、"~/.gvm/"ディレクトリを削除してください
ターミナルを再起動するか下記を実行してgvm
コマンドを実行できるようにします
source ~/.gvm/scripts/gvm
これにてgvm本体のインストールは完了です
$ gvm version Go Version Manager v1.0.22 installed at ~/.gvm
Go 1.6をインストールする
参考にした書籍が1.6を推奨していたので1.6.3をインストールしようとしましたが・・
$ gvm install go1.6.3 Downloading Go source... Installing go1.6.3... * Compiling... ERROR: Failed to compile. Check the logs at ~/.gvm/logs/go-go1.6.3-compile.log ERROR: Failed to use installed version
エラー通り".gvm/logs/go-go1.6.3-compile.log"を見てみます
##### Building Go bootstrap tool. cmd/dist ERROR: Cannot find ~/.gvm/gos/go1.4/bin/go. Set $GOROOT_BOOTSTRAP to a working Go tree >= Go 1.4.
どうやら1.5からはセルフホスティングされているため、ビルドに1.4以上が必要らしいです
そこで1.4をインストールしようとしましたが・・
$ gvm install go1.4 Installing go1.4... * Compiling... ERROR: Failed to compile. Check the logs at ~/.gvm/logs/go-go1.4-compile.log ERROR: Failed to use installed version
エラー通り"~/.gvm/logs/go-go1.4-compile.log"を見てみます
# Building C bootstrap tool. cmd/dist # Building compilers and Go bootstrap tool for host, darwin/amd64. lib9 libbio liblink cmd/cc cmd/gc cmd/6l cmd/6a cmd/6c ~/.gvm/gos/go1.4/src/cmd/6c/txt.c:995:28: error: shifting a negative signed value is undefined [-Werror,-Wshift-negative-value] ~/.gvm/gos/go1.4/src/cmd/6c/txt.c:1045:28: error: shifting a negative signed value is undefined [-Werror,-Wshift-negative-value] go tool dist: FAILED: clang -Wall -Wstrict-prototypes -Wextra -Wunused -Wno-sign-compare -Wno-missing-braces -Wno-parentheses -Wno-unknown-pragmas -Wno-switch -Wno-comment -Wno-missing-field-initializers -Werror -fno-common -ggdb -pipe -Wuninitialized -O2 -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -mmacosx-version-min=10.6 -c -m64 -I ~/.gvm/gos/go1.4/include -I ~/.gvm/gos/go1.4/src/cmd/6c -o ~/.gvm/gos/go1.4/pkg/obj/cmd/6c/txt.o ~/.gvm/gos/go1.4/src/cmd/6c/txt.c
上のIssueを見る感じMacだとインストールできないとかなんとか(ちゃんと読んでいないです)
そこでバイナリからインストールします
gvm install go1.4 -B gvm use go1.4 export GOROOT_BOOTSTRAP=$GOROOT
改めて1.6.3をインストールします
gvm install go1.6.3 gvm use go1.6.3
ようやく無事にインストールできた模様フー ( ̄‥ ̄) = =3
$ gvm list gvm gos (installed) go1.4 => go1.6.3 system
Hello World!
最後にちょろっとHello World!だけ動かしてみました
package main import ( "fmt" ) func main() { fmt.Println("Hello World!") }
$ go run hello.go Hello World!
コンパイラ言語なのにこの手軽さはいいですね!!
参考URL
一昨日に開催された第2回 botソンに参加して画像レスbotを作成した話
2016年07月09日、株式会社トレタ様で開催されたbotハッカソンこと通称botソンに参加してきました。個人でもくもく開発して最後に発表といった感じの勉強会です
この記事はその勉強会で作った簡単に画像レスをするためのSlack botの紹介みたいなもので、Herokuの使い方などについては触れませんのでご了承ください
背景
最近、Slack Teamを作ったのですが、やっぱり文字やアイコンばかりだと盛り上がりにかけ、誰も発言しなくなる => 過疎のコンボに繋がると思いました
かといって、下記にもあるようにおもしろ画像をセコセコと探しているのを誰かに見られるとものすごい萎えます(ちなみに僕は画像レス用のディレクトリをDropboxに持っていますが、そこから画像を選別しているのを見られるのも嫌です)
オモシロ画像を貼るためにせっせとマウスでURLをコピペする姿も、ウケるために必死な感じが出てしまいますしあまり人に見られたくありません
なので今回は、なるべく少ない手数で、それこそLINEスタンプ感覚で画像レスができるように、 レス画像検索サイトTiqavのAPIとGoogle Custom Search APIを使ってメッセージのとあるキーワードに反応して自動的に画像レスを行ってくれるSlack Botを作りたいと思いました
構成
1年ほど前からHerokuは無料プランでは1日18時間しか使用できなくなったし・・普段RubyばっかでNodeほとんど書かないし、Rubotyとかあるし・・とか思ったのですが、やっぱり一番情報が集めやすそうなHerokuとHubotという構成にしました
近年のベストプラクティスみたいなものがあればぜひ教えていただきたいです
無料プランはほっておくとSleepに入ってしまうため、New RelicでPingを送ってあげたり、1日18時間しか使用できないので、Process Schedulerというアドオンを使って意図的に眠らしてあげたりする必要があります
Tiqav API
Tiqavは画像レスを検索するためのサイトでAPIも公開しています。大体の画像が漫画系なのもいいです
Tiqav
Tiqav API
今回はSearch APIとサムネイル用のImage URLを使います
Search API
GET search
http://api.tiqav.com/search.json?q=[query]&callback=[fucntion_name]
GET search/random
http://api.tiqav.com/search/random.json?&callback=[fucntion_name]
Example response
[ {"id":"3om","ext":"jpg","height":1442,"width":1036,"source_url":"http://example.com/image1.jpg"}, {"id":"1eb","ext":"jpg","height":171,"width":250,"source_url":"http://example.com/image2.jpg"} ]
Image URL
Search APIのResponseにはTiqav上の画像URLが含まれていません(Source URLはすでにNot Foundになっていることが多い)
そこで、ResponseのIDとEXTを組み立ててTiqav上の画像のURLに変換します
http://img.tiqav.com/[id].[ext]
所感
Tiqavの画像はほとんどが漫画画像だと思われるのでキーワードに対する漫画画像のレスポンス率は非常に高いです(tsで発火するようにしてた)
ただし、検索が結構あいまいなところがあり、下記のように意思疎通でできていないことも多いです(getsで発火するようにしてた)
また、Googleと違ってフィルタリングができないため、「ピー」な画像を引くこともたまにあります
誰かに見られたらたまりません
というような問題があったためTiqavに対応してからGoogleにも対応することにしました
Google Custom Search API
無料枠だと1日100回までしかリクエストしか受け取れず、結構さんさんたる言われようですが、検索精度は流石だと思います
なお、Custom Search APIを使用するにはCustom Search API KeyとAPIで使用するCustom Search Engineを指定する必要があるため、API KeyとEngine IDをそれぞれ取得する必要があります
1. Custom Search API
2. Custom Search Engine
それぞれこちらの方が非常に分かりやすく解説してくださっています
また、Custom Search APIのドキュメントはこちらになります
API Reference | Custom Search | Google Developers
Search API
GET search
https://www.googleapis.com/customsearch/v1
Parameters
とりあえず以下のパラメータはつけておきましょう
Name | Description |
---|---|
key | ①で取得したCustom Search API Key |
cx | ②で取得したCustom Search Engine ID |
q | 検索キーワード |
searchType | 検索タイプ |
qには任意の文字列を、searchTypeには画像を検索するために"image"を指定します
Example response
すみません、レスポンスは少し長いので省略します
ただ、Google Search APIは使用制限があるため、実際に使用する前に①のサイトのこの API を API Explorer で試す
というリンクでしっかりテストをするといいと思います
Filtering
こちらはTiqavと違ってただのGoogle画像検索なので「ピー」な画像を引く可能性も高く、漫画画像以外の画像もいっぱいレスポンスに含まれてしまっています
前者に関してはGoogleにはセーフサーチという機能があるのでそれにあやかります
後者に関してもImageMagickで画像の彩度を図ってフィルタリングしようとしたのですが、そもそもGoogle Custom Engineにカラーのフィルタリング機能も備わっていたためこれを使用することで解決しました(Google検索すげー)
Name | Description |
---|---|
safe | 検索セーフレベル("high", "medium", "off") |
imgColorType | 画像カラータイプ("color", "gray", "mono") |
それぞれ"high"と"gray"を選択しました。"mono"より"gray"がちょうどよかったです
セーフサーチはお好みで外してください
所感
検索精度の高さ、検索結果の多さがTiqavの比ではないため、漫画のセリフを入れると大体帰ってくるのがすごいですし、紹介した以外にもたくさんフィルタリング機能があるように見えます
ただし、漫画画像に特化した検索エンジンというわけではないので、グレースケールに近い画像が多く含まれそうなキーワードを入れると、漫画画像以外が返ってきます
なので、うまく使い分けれれば大体のキーワードはなんとかなりそうな気がしました
ソースコード
ソースコードは僕のGit Hubに公開しているので、自由に見ることができますが、一部だけ簡単な解説を入れようと思います
shuffle = (array) -> # For clone arr = array.slice() i = arr.length while --i j = Math.floor(Math.random() * (i + 1)) tmp = arr[i] arr[i] = arr[j] arr[j] = tmp arr # Avoid to be cached same url image by Slack get_timestamp = () -> (new Date()).toISOString().replace(/[^0-9]/g, '') send_with_tiqav = (msg, path, query = {}) -> msg.http(path).query(query).get() (err, res, body) -> json = JSON.parse body if json.length > 0 items = shuffle json msg.send "http://img.tiqav.com/#{items[0].id}.th.#{items[0].ext}?#{get_timestamp()}" send_with_google = (msg, path, query = {}) -> msg.http(path).query(query).get() (err, res, body) -> json = JSON.parse body if json.items.length > 0 items = shuffle json.items.slice(0, 3) msg.send "#{items[0].link}?#{get_timestamp()}" module.exports = (robot) -> robot.hear /(.*?) tr/i, (msg) -> send_with_tiqav msg, 'http://api.tiqav.com/search/random.json' robot.hear /(.*?) ts/i, (msg) -> keyword = msg.match[1] send_with_tiqav msg, 'http://api.tiqav.com/search.json', {q: keyword} robot.hear /(.*?) gs/i, (msg) -> keyword = msg.match[1] send_with_google msg, 'https://www.googleapis.com/customsearch/v1', {key: process.env.GCS_KEY, cx: process.env.GCSE_ID, q: keyword, searchType: 'image', imgColorType: 'gray', safe: 'high'}
1
毎回同じ検索結果が表示されると面白くないため、検索結果からランダム取得をしてきています。JavaScriptで配列をシャッフルする方法にもいろいろとあるのですが、Math.random()
だけだと偏るので、Fisher-Yatesアルゴリズムを使っています
下記サイトでアルゴリズムごとの偏りがグラフで見れるので是非確認してみてください
2
Slackは画像URLを自動的に画像に展開してくれるため、Content-Typeを指定する必要もなく楽でいいですが、同じ画像が使用されると
Pssst! I did not unfurl #{url} because it was already shared in this channel quite recently (within the last hour) and I didn't want to clutter things up.
といって画像を展開してくれないため、画像URLにパラメータとしてTimestampを付与しています(これはどっちでもいいかな)
さいごに
結果として、そこそこの頻度で期待している画像レスが返せるようになったので満足しています
あとはブラックリストを作ったり、画像解析をやっていくともっとやれることもありそうなのですが、その辺りはおいおいやってみて、もしかしたら記事にするかもしれません
参考URL
RailsとMySQLでiOSの絵文字に対応(UTF8MB4化)した話
兼ねてからちょこちょこエラーが出ていたiOSの絵文字を含んだデータにようやく対応しましたので、その備忘録です。
Railsは3.2.11、MySQLは5.6.25です。
ちなみにMySQLは5.5以降からUTF8MB4に対応しています。
はじめに
文字コードをUTF8からUTF8MB4に変更をするにあたっていくつかの注意点があります。
コレーション問題
UTF8MB4のコレーションをデフォルトにしたままだと、寿司ビール問題("🍣"と"🍺"が同じものとして扱われる)と言われる問題に遭遇し、コレーションをUTF8MB4_UNICODE_520_CIにすると、ハハパパ問題("ハ"と"パ"が同じものとして扱われる)と言われる問題に遭遇します。
そのため、ハハパパ問題を気にしない場合(そんな国内サービスはあるのか!?)はUTF8MB4_UNICODE_520_CIを、気にする場合は、コードポイントでの比較が可能なUTF8MB4_BINにする必要があります。
しかし、UTF8MB4_BINでは"A"と"a"は別のものとして扱われるので、それを許容する仕様である必要があります。
文字列のバイト長問題
UTF8が1文字あたり3バイトであるのに対し、UTF8MB4は1文字あたり4バイトになります。故に、最大で255バイトまでしか格納できないTINYTEXTカラムでは、 UTF8では85文字まで、UTF8MB4では63文字までしか格納できません。 そのため、63文字以上を格納したい場合は、より大きい型に変更する必要があります。
インデックスのバイト長問題
デフォルトでは最大インデックス長は767バイトですので、UTF8では255文字まで、UTF8MB4では191文字までしかインデックスを張れません。
しかし、こちらはMySQL 5.5.14以降からINNODB_LARGE_PREFIXオプションで最大3072バイトまで拡張できるので、そんなに大きな問題ではないです。
背景
UTF8MB4に対応していない場合、文字列が4バイトコードを含んでいるとそれ以降の部分がMySQL側で自動的にカットされてしまいます。
"てすと🍀" => "てすと"
そのため、nameにユニークキーを貼っているときに、
Hoge.where(name: "てすと🍀").first_or_create
みたいなコードを実行したら、以下のSQLが発行されるので、
select * from hoges where name = "てすと🍀" limit 1; insert into hoges (name) values ("てすと🍀"); # 実際には`name = "てすと"`が生成される
2回目以降のコード実行でWhereの段階では同じレコードが見つからなかったのに、Createの段階では同じレコードが見つかってDuplicationエラーが発生します。
概要
サーバのcharacter_set_*や既存データベース,既存テーブルの設定はなるべく変えたくない(インデックス長とかの諸々問題を考えて)ので、HogeテーブルのName属性の文字コードをUTF8MB4に変更します。
僕の場合は、ハハパパ問題を許容できない仕様だったのでコレーションはUTF8MB4_BINを選択します。
変更方法
まずはじめに、MySQL Clientで文字化けすると確認しづらいので、とりあえずこちらも文字コードをUTF8MB4に変更します。
"my.cnf"ファイル
[client] default-character-set = utf8mb4 [mysqld] character-set-server = utf8mb4
次に、文字コードにUTF8MB4を使用したいカラムの文字コードとコレーションを変更します。
alter table hoges modify column name varchar(80) character set utf8bm4 collate utf8mb4_bin not null;
このとき、Rails側の文字コードとMySQL側のコレーションのベースが一致しないと、下記のようなエラーが発生します。
ActiveRecord::StatementInvalid: Mysql2::Error: Illegal mix of collations (utf8mb4_bin,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation ..
なので、Rails側の文字コードの設定もUTF8MB4に変更します。
変更ファイルは"config/database.yml"ファイルです。
"config/database.yml"ファイル
development: . encoding: utf8mb4 . test: . encoding: utf8mb4 . staging: . encoding: utf8mb4 . production: . encoding: utf8mb4 .
また、レプリケーションにOctopusを使用している場合は、"config/shards.yml"ファイルも同様に変更する必要があります。
これで実際に絵文字が入っていることが確認できたら完了です。
それにしても、絵文字とそれにまつわる文字コード,コレーションの関係はややこしい・・
参考URL
MySQL :: MySQL 5.6 リファレンスマニュアル :: 10.1.11 以前の Unicode サポートから現在の Unicode サポートへのアップグレード
開発環境にMacを使用しているの方は要注意!SRMコマンド!
みなさん、開発環境には何を使っていますか?Linuxですか?Macですか?はたまたWindowsですかね?
ちなみに僕は家も会社もMacを使っています。
そしてMac以外をご使用の方はこの先を読む必要はあまりないかもしれません(読んでくれるとうれしいけどね)
先日、ファイルを削除でrm
コマンドを使おうとしたら、間違ってsrm
と打って実行してしまったのですが、
何もエラーは出ず何も標準出力もされず通ってしまいました。
^_^[~]$ srm hoge/huga/foo/bar.txt ^_^[~]$
そして、どうせ大したことないだろうと思っていたらファイルが消えていました・・
どうもsrm
コマンドはMacでファイルを完全消去するためのコマンドのようで、ゴミ箱で「確実にゴミ箱を空にする」を押したときに実行されるやつみたいです。
実行するとなんの面影もなく、ファイルが完全消滅してしまいます。
そんなコマンドがrm
コマンドにs
を追加するだけで簡単に使用でき、
使い方もrm
コマンドとほとんど変わらないので普段Macで開発している人は要注意です!
そんなわけで早速"zshrc"に以下を追加しました。
alias rm='rm -i' alias cp='cp -i' alias mv='mv -i' alias srm='srm -i' # new!
今回はたまたま消していいファイルだったのでよかったんですが、大事なファイルを削除しないためにも-i
オプションは付けておくようにしましょう。
参考URL
RailsとBundlerで`bundle exec`を省略した話とその時の副産物について
Railsアプリケーションの開発に使っているBundlerで一々bundle exec
を打つのって面倒ですよね。
調べてみるとrbenvのpluginだとかいろいろあるらしいのですが、
これまではずっとエイリアスでなんとか凌いでいました。
↓こんなやつ↓
alias rs='bundle exec rails server' alias rc='bundle exec rails console'
まあ、これでも別にいいんですが、最近たまたまGitHubを漁っていたら、良さ気な回避方法を使用しているプロジェクトがあったのでちょっと移行してみました。
多分、仕組み的にはrbenvのpluginとそんなに変わらないんじゃないかな・・
※以下はアプリケーションルートにいる前提です
まず、bundle install
時に--binstubs
を付けて、railsやrakeコマンドの実行ファイルのスタブを作成しておきます。
bundle install --binstubs #{path}
※#{path}を指定しなければ'bin/‘ディレクトリ以下に作成されますが、Rails 4では元のスクリプトが上書きされるので注意してください
これで./bin/rails
でrailsコマンドが実行できる訳ですが、このままだとパスが通っていないのであんまり便利じゃないっす!
ただ、普通にパスを通してしまうと全てのディレクトリから実行可能になってしまうので、以下のディレクトリを作成して、".zprofile"ファイルに以下を記述します。
mkdir -p .git/safe/
多分'.git/safe/‘ディレクトリに大きな意味はないです。
export PATH=.git/safe/../../bin:$PATH
※Bashなら". bash_profile"ファイルだっけ?
こうすることで、アプリケーションルートに".git/safe"ディレクトリが存在すれば、アプリケーションルートの"bin/“ディレクトリが実行パスに追加されるので、
アプリケーションルートでのみ実行可能で、かつbundle exec
を省略することができます。
実行パスに相対パスが来るのがなんか気持ち悪い気がしますが、仕組みが分かりやすいのでとりあえずこれに落ち着きました。
あと、僕は英語があんまり得意ではないので、もしかしたら本来の意図と違っているかもしれません・・( ̄ω ̄;)
これを応用すれば、ディレクトリレベルで実行可能なスクリプトやエイリアスっぽいものが使えそうな気がしました。
環境変数もあんまり汚さないのでいいのではないでしょうか?(これが副産物です)
参考URL
PATH=".git/safe/../../bin:$PATH" and do mkdir .git/safe in the root of repositories that you trust.
— Tim Pope (@tpope) 2012年2月4日
今更ながらXcode 7のBitcodeについてまとめてみた
タイトルにあるように今更ながら、Xcode 7でいろいろあったBitcodeについてまとめてみました。
まずはじめに、BitcodeとはXcodeのビルドフローにおける中間言語(LLVM IR)のバイナリ表現です。 LLVM IRにはテキスト表現とバイナリ表現の2種類がありますが、そのうちのバイナリ表現になります。
また、Xcodeの基本的なビルドフローは以下のようになります。
で、Xcode 7以降はデフォルトでBitcodeを含んだデータを生成するようになった感じです(もちろんBuild Settingsで無効にできます。詳しくはこの記事を)
Bitcodeを有効にすることでApple側でアーキテクチャに合ったコンパイルをしてくれるなど、メリットがあるのでなるべく有効にしておくといいと思います。
ちなみに、フレームワーク製作者の方はBitcodeに対応する場合、Build Settingsで有効にするだけだと駄目かもしれないです。詳しくは参考URLにあるのですが、xcodebuild
にOTHER_CFLAGS="-fembed-bitcode"
を設定すると多分いけると思います。
また、実際にアプリケーションに導入してテストする際に、通常のビルドではなくアーカイブまでしてください。じゃないとBitcodeのチェックが入らないので気付かないかもしれませんよ(経験済み)
Bitcodeに対応できていない場合、以下のようなエラーが出ます。
ld: bitcode bundle could not be generated because ~ was built without full bitcode. All object files and libraries for bitcode must be generated from Xcode Archive or Install build for architecture ~ clang: error: linker command failed with exit code 1 (use -v to see invocation)