iOSアプリをxcodebuildでビルドする(途中)
Appiumの前段階として、Simulatorなどにインストールするビルド済みのAppファイル*1*2が必要です。
メモ
そういうわけで、ターミナルから xcodebuild
を使って Appファイル
の作成を試します。
$ xcodebuild xcodebuild: error: The directory /Users/woshidan/path/ios-project/root/ does not contain an Xcode project. $ cd path/to/XcodeProject $ ls TestApp TestApp.xcodeproj TestAppUITests build
まずは、 XCodeで作成したプロジェクトのあるところ( .xcodeproj
ファイルのあるディレクトリ ) へ移動します。
依存しているライブラリのクラスのヘッダが見つからない ...
xcworkspace など依存ライブラリの設定が入ったファイルを、 -workspace
で指定しましょう。その際、 schema
も指定が必要です。
// # CocoaPodsを使っていてxcworkspaceを指定してビルドする $ xcodebuild -workspace ../../Test/TestLib.xcworkspace -scheme TestApp
CompileStoryboard TestApp/Base.lproj/Main.storyboard というメッセージが出てStoryBoardがビルドできない
Xcode
のバージョンによっては、特定の設定がないとビルドができないものがあります。そう、古い設定は新しいXCodeのバージョンが出るたびにビルドできなくなる可能性があるのです*3。
というわけでそういう場合は、xcodebuildで利用するXCodeのパスを古いものに xcode-select
で切り替えます。
# xcode-select -s /Applications/__oldXcode.app/Contents/Developer
シミュレータでビルドしてもらうよう指定する
-sdk iphonesimulator
オプションを追加してビルドします。
$ xcodebuild -workspace ../../Test/TestLib.xcworkspace -scheme TestApp -sdk iphonesimulator
のはずなんですが、めっちゃいっぱい ❌ /Applications/__oldXcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator9.3.sdk/usr/include/sys/_types.h:76:9: unknown type name '__uint32_t'; did you mean '__uint128_t'?
が出てつらいんで解決したらまたなんか書こう...。
*1:.appファイルはXCodeでビルドが完了すると $(PROJECT_DIR)/build/Release-iphoneos/xxxxx.app のようなパスに作成され、これを Payload フォルダに入れて圧縮 -> 拡張子を変更したものが .ipa ファイル https://developer.apple.com/jp/documentation/IDEs/Conceptual/AppDistributionGuide/TestingYouriOSApp/TestingYouriOSApp.html http://lain.heavy.jp/lain/2012/01/13/462 参照
*2:appiumのcapsファイルに指定するファイルは .ipa でも .app でもよさそう...?
*3:若干、いいすぎですが、メジャーバージョンが2~3離れたりしたら厳しい
今日のbash
&
... コマンドをバックグラウンドで実行する
参考: http://itpro.nikkeibp.co.jp/article/COLUMN/20060224/230589
例
$ heavy_command&
case
文 ... 他の言語のswitch と同じ
参考: http://shellscript.sunone.me/case.html
case 値 in パターン1 ) 処理1;; パターン2 ) 処理2 ;; パターン3 ) 処理3 ;; … パターンn ) 処理n ;;
)
の記法がマジでびびる。
getopts
参考: https://www.ibm.com/support/knowledgecenter/ja/ssw_aix_71/com.ibm.aix.cmds2/getopts.htm https://qiita.com/b4b4r07/items/dcd6be0bb9c9185475bb
コマンド・ラインの引数を処理し、有効なオプションを検査する。
こないだrubyでちょいとしたスクリプト書いてる時に引数検査をARGVでeach回してぐるぐるしてたんですけど、 あったわ〜 シェルにあったわ〜
って感じです。
getopts OptionString Name [Argument...]
OptionString
は、使用したいオプションの文字列。よくある例としては h
や help
で使い方を出力する、といったもの。
:
をつけるかどうかで振る舞いが変わり、 OptionString
の後ろに :
をつけると、そのオプションは引数を必要とするようになります。
指定していないオプションや引数を使った場合に
# https://qiita.com/b4b4r07/items/dcd6be0bb9c9185475bb より引用 ./test.sh: option requires an argument -- d ./test.sh: illegal option -- x
のようにエラー表示が出て終了しますが、 OptionString
の全体の前に :
をつけるとこのエラー表示は行われなくなり、自前でのエラー処理を行うことができます。
https://qiita.com/b4b4r07/items/dcd6be0bb9c9185475bb の記事が非常に参考になり、 getopts
のテンプレートなども紹介されているので今度便利コマンドを使う時は利用したいところです。
$!
... 最後に実行されたバックグラウンドコマンドのプロセスIDに展開
参考: https://qiita.com/laikuaut/items/1daa06900ad045d119b4
ちなみに現在動かしている(バックグラウンドでない)シェルのプロセス番号は $
で展開される。
$ echo $$ 521
会社のrubyのバージョンが2.4.0以降にあげられないので `Array#-` と同等のスニペットをおいておく
irb(main):010:0> class Array irb(main):011:1> def - other irb(main):012:2> copy = self.dup irb(main):013:2> other.each do |other_array_item| irb(main):014:3* copy.delete other_array_item irb(main):015:3> end irb(main):016:2> copy irb(main):017:2> end irb(main):018:1> end => :- irb(main):019:0> a = [1, 2, 3] => [1, 2, 3] irb(main):020:0> b = [1, 2, 4] => [1, 2, 4] irb(main):021:0> a - b => [3]
参考
自作クラスのテスト用にComparableモジュールと宇宙船演算子を使って同じオブジェクトか比較しやすくする
rubyでちょっとした処理を担当する自作クラスのテストをするとき、同じオブジェクトがどうかの比較する際、
assert_equal expect_obj.hash_value, actual_obj.hash_value # hash_valueはオブジェクトのidではないオブジェクトに特有の値
というような式をよく書いていました。ですが、そんなに広く使われないクラスであることがわかっているなら ==
演算子の挙動をいじってしまって、
assert_equal expect_obj, actual_obj
とかけるようにしちゃっていいかも、ということでその方法をメモ。
class MyClass include Comparable # 宇宙船演算子の内容を元に `<=`, `>=` を使えるようにしてくれる def <=> other # 宇宙船演算子を使って、`<`, `==`, `>` 用の動作を定義 return nil unless other.is_a? MyClass hash_value <=> other.hash_value # MyClassのオブジェクトが同一かどうか判断するための比較に、hash_valueの比較を使う end def hash_value # テストでも作りやすい値を元にハッシュ値を計算する end end
参考
- 作者: Peter J. Jones,arton,長尾高弘
- 出版社/メーカー: 翔泳社
- 発売日: 2015/01/09
- メディア: 大型本
- この商品を含むブログ (13件) を見る
rubyでライブラリなどを書くとき、Rakefileと相対パスのrequireを使ってクラスの取得やテストをやりやすくする
+---+ lib | +-+ some_module | +-+-- a_processor | | +-- order.rb | | +-- item.rb | +-- b_processor | | +-- order.rb | | +-- item.rb | +-- composer.rb # composerは a_processor, b_processor 以下のクラスを必要とする +---+ test # ここから一括で回せるようにしたい +-+ some_module +-+-- a_processor | +-- order_test.rb | +-- item_test.rb +-- b_processor | +-- order_test.rb | +-- item_test.rb +-- composer_test.rb
といった構成のライブラリを作るとして、composer
書いたり、 地味にテストを自動実行できるようにどうしたら良いか調べるのがめんどくさかったのでメモ。
追加分
+---+ lib | +-+ some_module | +-+-- a_processor | | +-- order.rb | | +-- item.rb | +-- b_processor | | +-- order.rb | | +-- item.rb | +-- composer.rb | +-- a_processor.rb ** 追加 | +-- b_processor.rb ** 追加 +---+ test + Rakefile ** 追加 +-+ some_module +-+-- a_processor | +-- order_test.rb | +-- item_test.rb +-- b_processor | +-- order_test.rb | +-- item_test.rb +-- composer_test.rb
それっぽく他パッケージにあるクラスを全て読み込む
比較的苦しくない抑えどころに近いんですが、そのパッケージのクラスを丸ごと読み込んでくれるファイル用意して、それを require
すると楽そう。
# a_processor.rb require "#{File.dirname(__FILE__)}/a_processor/order.rb" require "#{File.dirname(__FILE__)}/a_processor/item.rb"
ただ、明示的にクラスの指定どうこうする必要がない場合は、 Dir
クラスなどを使って each で回すと良さそう。
# a_processor.rb をなくしてbuilder.rb 冒頭で Dir.glob("#{File.dirname(__FILE__)}/a_processor/*").each do |file| require file end
test以下のディレクトリのファイル全てをコマンド一つで実行する
今回は test
ディレクトリ以下で rake test
で全部実行できればよかったので、下記のような Rakefile
を test
直下に置く。
Rakefile
はおいたところで Rakefile
に書いたタスクが rake xxx
(xxxなしだと task :default
に定義したものが使われる)実行されるようになるので、書いてから、普通はトップディレクトリにおいて、 ./**/*_test.rb
-> ./test/**/*_test.rb
にしたほうがいいかとも思った。
# Rakefile # coding: UTF-8 require 'rake/testtask' task :default => [:test] Rake::TestTask.new do |test| test.test_files = Dir['./**/*_test.rb'] test.verbose = false end
なお、テストファイルで本番用のファイルを要求するときは、そのライブラリ用のベースクラス的なのを用意して、そこで require
しておくと楽。
# base_test.rb require 'test/unit' Dir.glob("#{File.dirname(__FILE__)}/a_processor/*").each do |file| require file end Dir.glob("#{File.dirname(__FILE__)}/b_processor/*").each do |file| require file end Dir.glob("#{File.dirname(__FILE__)}/**.rb").each do |file| require file end class SomeModule::BaseTest < Test::Unit::TestCase include SomeModule ... # 他のテスト用クラスは require "#{File.dirname(__FILE__)}/path/to/base_test.rb" class SomeModule::SomeTest < SomeModule::BaseTest
参考
gitのローカルリポジトリからお目当のタグを抽出する
今日は時間がないので渾身かも、と思ったコードに数行コメントつけてPOST!
- シェルは便利なんだけどシェルの結果の文字列を気軽に処理したい時、ruby書いたことある人にとってはrubyがとても楽
- rubyだとシェルのコマンドを
%x( command )
などで実行できる ruby xx.rb --params
などのコマンドライン引数はARGV
に配列で入ってる- 一時的にディレクトリを移動したいだけなら
Dir.chdir
にブロック渡すのが便利 - 他の人とディレクトリ構造が違う(ホームディレクトリなどは?) =>
ENV['HOME']
などENV
から取れるよ git fetch remote-repo --tags
で現在のステージの内容などを気にせずにgit tag
の出力だけ更新できるよgit tag
の出力はgit FETCH_HEAD
にあるtag
と一致していて*1、要するにgit
の管理対象のファイルの内容を読み書きしているわけではないので- 作業途中で同期のための雑な
git stash
しなくていいの嬉しい!
latest_tag = Dir.chdir("#{ENV['HOME']}/woshidan-test/sample-repo") do if fetch_remote puts "fetch tags from remote repository ..." %x( git fetch remote-repo --tags ) # ローカルリポジトリを最新にするコマンドを挟むことで自分を信じないことができる puts "done" end %x( git tag ).split("\n").select { |tag| tag.match(/お目当のタグの正規表現/) }.last end
参考
- http://uxmilk.jp/12947
- https://www.xmisao.com/2014/03/01/how-to-execute-a-shell-script-in-ruby.html
- http://blog.codebook-10000.com/entry/20140325/1395673232
*1:このファイルから出力されているわけではないだろうが
AWS CLIの設定ファイルにて名前付きプロファイルを利用して手軽にAWS CLIのIAMユーザを切り替える
普段業務でAWS CLIを使っているため、業務本番用のアカウントとちょっと個人の調査用のアカウントを分けて使いたいわけですが*1、 aws configure
コマンドで設定できるアカウントは一つだけです。
これではちょっと調査をするたびにクレデンシャル情報を引っ張ってきて入力するのがめんどくさくなるのが目に見えているので他の方法を考えます。
aws configure コマンドで何をしているか
aws configure
コマンドで何をしているかというか、 ~/.aws/config
と ~/.aws/credentials
にコマンドで与えた引数の入力を行なっています。
入力結果のファイルは下記のような形です。
~/.aws/config
[default] region = ap-northeast-1
~/.aws/credentials
[default] aws_access_key_id = ABCDEEGHEXAMPLEKEYID aws_secret_access_key = ABCdefgHIjkLM/OPQrstUVwxyzAbcsExampleKey
このファイルに何か見出しつけてもう1組書いてやったらできそうですね。
awsの設定ファイルで名前付きプロファイルを使う
[XXX]
のように見出しをつけて、認証情報などをその見出しごとに管理でき、これを 名前付きプロファイル
と言うそうです。
~/.aws/config
[default] region = ap-northeast-1 [profile user2] // credentialsと見出しが違うので注意 region=us-east-1 output=text // 出力形式も設定できる
~/.aws/credentials
[default] aws_access_key_id = ABCDEEGHEXAMPLEKEYID aws_secret_access_key = ABCdefgHIjkLM/OPQrstUVwxyzAbcsExampleKey [user2] aws_access_key_id=AKIAI44QH8DHBEXAMPLE aws_secret_access_key=je7MtGbClwBF/2Zp9Utk/h3yCo8nvbEXAMPLEKEY
このように見出しをつけて、
$ aws ec2 describe-instances --profile user2
のように --profile
オプションをつけて実行するか、
$ export AWS_PROFILE=user2
のように環境変数を設定することでaws cliで利用するユーザーアカウントを切り替えることができます。
現場からは以上です。