2013年10月6日日曜日

"Harp"ってフロントエンドエンジニアに良さげなWebサーバーを試してみた

このエントリーをはてなブックマークに追加 はてなブックマーク - "Harp"ってフロントエンドエンジニアに良さげなWebサーバーを試してみた

HarpってWebサーバーがイケてそうなのでとりあえず試してみました。 YouTubeで紹介された奴を割とそのまま試しただけなので何もすごくないですが。

少し確認してみたのですが、インストールも1コマンドで出来て手軽だし、Markdown,LESSとかTwitterBootstrap使ってるWebエンジニアにとってはかなり有用なのではないかと思いました。

以下参考サイトです。

Harp公式サイト Harp

Harpの紹介サイト(多分作者の人?) Introducing Harp

Harpの紹介YouTube Introduction to Harp Web Server

目次

  1. Harpって?
  2. インストールしてみる
  3. とりあえず試す
  4. Markdown見てみる
  5. BootstrapのLESSをコンパイルしてみる
  6. 最後に

1.Harpって?

  • Webサーバーですよ
  • インストールはNodeのnpm使うよー
  • Markdown,EJS,CoffeeScript,LESS,Stylusとか解釈してくれますよー
  • コンパイルしてPureなHTMLとかCSS生成できるよー

他にも色々あるのかもしれませんが、とりあえず自分が試してみたのは上記機能のみです。

2.インストールしてみる

npm使うのでNodeを予めインストールしておく必要があります。 どのバージョンが必要であるかという明記はなかったような気がしましたが、とりあえず自分はv0.10.11とかでとりあえず動きました。

以下のコマンドでOKです。

$sudo npm install harp -g

終わり!!!

3.とりあえず試す

公式に従ってharpコマンドを使ってテンプレートプロジェクト作ってみます。

$harp init myproject

とするとカレントディレクトリにmyprojectってフォルダが出来て、中に色々ファイルが出来てます。

-rwxr-xr-x  1 toshihirock  staff   52 Oct  6 08:08 404.jade
-rwxr-xr-x  1 toshihirock  staff   81 Oct  6 08:08 _layout.jade
-rwxr-xr-x  1 toshihirock  staff   52 Oct  6 08:08 index.jade
-rwxr-xr-x  1 toshihirock  staff  259 Oct  6 08:08 main.less

まあ、とりあえずWebサーバー起動して見てみると。

$harp server myproject

          _____                    _____                    _____                    _____          
         /l    l                  /l    l                  /l    l                  /l    l         
        /::l____l                /::l    l                /::l    l                /::l    l        
       /:::/    /               /::::l    l              /::::l    l              /::::l    l       
      /:::/    /               /::::::l    l            /::::::l    l            /::::::l    l      
     /:::/    /               /:::/l:::l    l          /:::/l:::l    l          /:::/l:::l    l     
    /:::/____/               /:::/__l:::l    l        /:::/__l:::l    l        /:::/__l:::l    l    
   /::::l    l              /::::l   l:::l    l      /::::l   l:::l    l      /::::l   l:::l    l   
  /::::::l    l   _____    /::::::l   l:::l    l    /::::::l   l:::l    l    /::::::l   l:::l    l  
 /:::/l:::l    l /l    l  /:::/l:::l   l:::l    l  /:::/l:::l   l:::l____l  /:::/l:::l   l:::l____l 
/:::/  l:::l    /::l____l/:::/  l:::l   l:::l____l/:::/  l:::l   l:::|    |/:::/  l:::l   l:::|    |
l::/    l:::l  /:::/    /l::/    l:::l  /:::/    /l::/   |::::l  /:::|____|l::/    l:::l  /:::|____|
 l/____/ l:::l/:::/    /  l/____/ l:::l/:::/    /  l/____|:::::l/:::/    /  l/_____/l:::l/:::/    / 
          l::::::/    /            l::::::/    /         |:::::::::/    /            l::::::/    /  
           l::::/    /              l::::/    /          |::|l::::/    /              l::::/    /   
           /:::/    /               /:::/    /           |::| l::/____/                l::/____/    
          /:::/    /               /:::/    /            |::|  ~|                       ~~          
         /:::/    /               /:::/    /             |::|   |                                   
        /:::/    /               /:::/    /              l::|   |       Harp v0.9.3                 
        l::/    /                l::/    /                l:|   |       Asset Pipeline Framework    
         l/____/                  l/____/                  l|___|       By Chloi Inc. 2012-2013     

Your server is listening at http://localhost:9000...

デフォルトだと9000ポートでWebサーバーが起動するみたいなのでhttp://localhost:9000早速アクセス。

すごい、簡単だー。

4.Markdown見てみる

今度はテンプレート使わずやってみましょう。

$mkdir markdowntest
$cd markdowntest
$vi index.md
#Hello World
##Hello World2
    
+ test
+ test
$harp server --port 9000

これで同じくアクセス。

すばらしい。

5.BootstrapのLESSをコンパイルしてみる

YouTuebの紹介でもBootstrapのLESS使ってコンパイルしてーみたいな事をやっていたので、全く同じ方法でやります。

とりあえずTwitter Bootstrapをダウンロードしてくる。

Bootstrap

で解凍。

あと今回用にサンプルプロジェクト作って解凍したBootstrapからLESSを持ってきます。あと名前も変えます。

$mkdir bootstraptest
$cd bootstraptest
$cp -r ~/Downloads/bootstrap-3.0.0/less ./_bootstrap

TwitterBootstrapのLESSを読み込む用のlessを作成します。

$vi main.less
@import "_bootstrap/bootstrap";
body {
  background: @brand-primary;
}

1行目でBootstrapのすべてのLESSをインポートしているbootstrap.lessを読み込んでいます。 3行目ではBootstrapで定義してる変数を利用して背景色を指定しています。

テスト用のHTML作ってみます。

$vi index.html
<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="main.css" rel="stylesheet">
  </head>
  <body>
    <h1>Hello, world!</h1>
  </body>
</html>

見てみます。

おー、しっかり背景色が変わっています。

さて、compileコマンドを使ってコンパイルします。

$harp compile --output ../www

終わるとwwwディレクトリが出来ています。

$ll ../www/
-rw-r--r--  1 toshihirock  staff     224 Oct  6 08:55 index.html
-rw-r--r--  1 toshihirock  staff  100869 Oct  6 08:55 main.css

綺麗にコンパイルされてます。 あら、素敵!

6.最後に

個人的にですが、Gruntとか使ってみたいけど敷居高そうだなーと考えている人には良いのでは?という感じでした。

上記ぐらいの利用法であれば特に詰まる事なくできたので、そいう手軽さもすごい良いなと。

2013年9月28日土曜日

[Tizen]よく使うsdb(Smart Development Bridge)コマンドの使い方メモ

このエントリーをはてなブックマークに追加 はてなブックマーク - [Tizen]よく使うsdb(Smart Development Bridge)コマンドの使い方メモ

Tizenのエミュレーターや実機へのアプリ転送などをコマンドライン上で行えるsdb(Smart Development Bridge)がTizen SDKに同梱されています。 これはAndroidでいうadbコマンドのTizen版になります。

上記を利用する事でIDEを介さず、エミュレーターや実機にして操作が出来るのでよく使う機能などをメモを記載します。 (詳細はsdb helpコマンドで見れます)

  • sdbコマンドの場所
  • 接続されているTizenデバイスの確認
  • sdbコマンドの対象デバイスの指定
  • Tizenデバイスへのアプリ(tpk,wgt)のインストール
  • Tizenデバイスへのリモートログイン
  • Tizenデバイスからのファイル取得
  • Tizenデバイスへのファイル転送
  • その他

sdbコマンドの場所

Macの場合、$TIZEN_HOME/tools/sdbです。 パスは忘れてしまいましたが、Ubuntu、Windowsでも同様にsdbコマンド自体は利用可能です。(Windowsの場合にはコマンドプロンプト)

予め、.bashrcなどでパスを通しておくと便利です。 私の環境では以下のような感じ。

$export PATH=$PATH:/Users/toshihirock/tizen-sdk/tools

接続されているTizenデバイスの確認

エミュレーターや実機で現在PCに接続されていると認識しているTizenデバイス一覧を表示するにはsdb devicesコマンドを利用します。

$ sdb devices
* daemon not running. starting it now on port 26099 *
* daemon started successfully *
List of devices attached 
emulator-26100  device  mini
emulator-26110  device  abc1

List of devices attached配下に端末一覧が表示されています。 上記例ではminiabc1という名称のエミュレーターを2つ起動しています。

実機の場合にも、上記と同じように表示されます。 もし、実機が表示されない場合、端末のUSBデバッグモードが有効化されていない、もしくはUSBドライバがインストールされていない可能性があります。

なお、上記例ではdaemon not running. starting it now on port 26099ということでsdbサーバが同時に起動しています。

コマンドで明示的に起動する場合、sdb start-serverとすることで対応できますが、上記のように起動していなければ勝手に起動してくれるみたいなので個人的にはあまり使いません。(逆に停止する場合にはsdb kill-serverコマンドを利用します)

sdbコマンドの対象デバイスの指定

複数のTizenデバイスを接続している場合、どの端末に対してsdbコマンドを発行するか指定する必要があります。

対象が実機であるか、エミュレーターの違いかである場合にはオプションで-d-eを利用するのが便利です。(installコマンドについては後述)

$sdb -d install example.wgt
$sdb -e install example.wgt

-dオプションで実機(device)、-eオプションでエミュレーター(emulator)に対して指定したコマンドを実行しています。

実機を2台以上接続してる、エミュレーターを2台以上接続してる時はどうするかというとsdb devicesコマンドを利用してそれぞれのSerial Numberを取得し、オプションで-sを利用して指定します。

$sdb devices
List of devices attached 
emulator-26100  device  mini
emulator-26110  device  abc1
$sdb -s emulator-26100 install example.wgt

上記例ではまず、sdb devicesコマンドでそれぞれのSerial Numberを確認しています。 Serial Numberは一番左の名称が該当しています。(この例ではemulator–26100とemulator–26110)その後、-sオプションんを使用してSerial Numberが「emulator–26100」の方にアプリをインストールしています。

Tizenデバイスへのアプリ(tpk,wgt)のインストール

作成したtpk、wgtをTizenデバイスにインストールする場合にはsdb installコマンドを利用します。

$sdb -e install example.wgt

上記例ではexample.wgtというアプリをエミュレーターインストールしています。 既に上記アプリがインストールされている場合にも上記コマンドで上書き更新してくれます。

Tizenデバイスへのリモートログイン

Tizenデバイスにリモートログインする場合、sdb shellコマンドを利用します。なお、TizenIDEのConnection ExploerでもGUIでファイル構成などが確認できます。

$sdb -e shell
sh-4.1$

上記例ではエミュレーターにリモートログインしています。

普通にコマンドも使えます。

sh-4.1$ ls -la
total 88
dr-xr-xr-x  24 root root  4096 2013-07-17 20:38 .
dr-xr-xr-x  24 root root  4096 2013-07-17 20:38 ..
dr-xr-xr-x   2 root root  4096 2013-07-17 20:37 bin
dr-xr-xr-x   2 root root  4096 2013-06-14 10:38 boot
drwxr-xr-x   2 root root  4096 2013-07-17 20:36 cache
drwxr-xr-x   2 root root  4096 2013-08-03 23:36 csa
drwxr-xr-x   2 root root  4096 2013-07-17 20:36 data
drwxr-xr-x  15 root root  3700 2013-09-28 06:17 dev
drwxr-xr-x  39 root root  4096 2013-08-03 23:36 etc
lrwxrwxrwx   1 root root     9 2013-07-17 20:36 home -> /opt/home
dr-xr-xr-x   9 root root  4096 2013-07-17 20:37 lib
drwx------   2 root root 16384 2013-07-17 20:36 lost+found
drwxr-xr-x   2 root root    40 2013-09-28 06:17 media
drwxr-xr-x   9 root root  4096 2013-07-17 20:37 mnt
drwxr-xr-x  14 root root  4096 2013-07-17 20:37 opt
dr-xr-xr-x 108 root root     0 2013-09-28 06:17 proc
lrwxrwxrwx   1 root root    14 2013-07-17 20:36 root -> /opt/home/root
drwxr-xr-x  12 root root   340 2013-09-28 06:17 run
dr-xr-xr-x   2 root root  4096 2013-07-17 20:38 sbin
lrwxrwxrwx   1 root root     8 2013-07-17 20:36 sdcard -> /mnt/mmc
drwxr-xr-x   2 root root     0 2013-09-28 06:17 smack
drwxr-xr-x   2 root root  4096 2013-06-14 10:38 srv
dr-xr-xr-x  12 root root     0 2013-09-28 06:17 sys
drwxr-xr-x   2 root root  4096 2013-07-17 20:36 system
drwxrwxrwt  12 root root  1700 2013-09-28 06:43 tmp
drwxr-xr-x  16 root root  4096 2013-07-17 20:38 usr
drwxr-xr-x  16 root root  4096 2013-07-17 20:36 var

suコマンドでスーパーユーザーにもなれます。

上記より、例えばIDEのコンソールなどでhogeっていうファイルを吐き出したよって言っているけどそれってどこなんだって言うときにはsdb shellでリモートログインしてfindコマンドで探すっていうのが手っ取り早いです。

sdb shell -ls -laなどとコマンドを指定するとリモートログインすることなく、コマンドの実行も可能なようです。

Tizenデバイスからのファイル取得

Tizenデバイスからファイルを取得する場合、sdb pullコマンドを利用します。

$sdb -e pull /opt/usr/media/Images/Default.jpg ~/Downloads/
1 file(s) pulled. 0 file(s) skipped.
/opt/usr/media/Images/Default.jpg   5834 KB/s (632118 bytes in 0.105s)

上記例ではTizen端末の/opt/usr/media/Images/Default.jpgファイルをローカルPCの~/Downloads/においてね、という操作をしています。

Tizenデバイスへのファイル転送

Tizenデバイスへファイルを配置する場合、sdb pushコマンドを利用します。

$sdb -e push ~/Downloads/icon.jpg /opt/usr/media/Images/
1 file(s) pushed. 0 file(s) skipped.
/Users/toshihirock/Downloads/icon.jpg   210 KB/s (2799 bytes in 0.013s)

上記例ではローカルPCの~/Downloads/icon.jpgというファイルをTizen端末の/opt/usr/media/Images/においてね、という操作をしています。

sdb pullとsdb pushでは第1引数と第2引数の意味が違うので注意です。

その他

上記以外でもsdb uninstallでアプリをアンインストールしたり、やsdb dlogでログを見たりできますが、個人的にあまり使わないので割愛します。その他にもコマンドなどありますが、詳細はsdb helpで確認下さい。

[TIzen]アプリ転送時に「There is no device to launch」というダイアログが表示される場合

このエントリーをはてなブックマークに追加 はてなブックマーク - [TIzen]アプリ転送時に「There is no device to launch」というダイアログが表示される場合

エミュレーターを起動しているにも関わらず、IDEからRun Asでアプリをエミュレーターに転送しようとした際にThere is no device to launchというダイアログが表示される事があります。

上記の場合、Tizen IDEでConnection Exploerウィンドウを開けば問題が解消されます。

Tizen IDEをインストールした場合にはデフォルトで上記Windowは表示している状態だったと思いますが、消してしまった場合、Tizen IDEのWindow→Show View→Other→Tizen→Connection Exploerで再表示可能です。

また、上記ウィンドウでエミュレーターを含む現在sdbで認識しているデバイスが表示されるので、そこにエミュレーター(実機)があるかも確認できます。

sdbコマンドを利用することでアプリの転送も可能ですが、別の機会に!

2013年8月10日土曜日

[Tizen][Jenkins]TizenネイティブアプリをJenkinsでビルドした時のメモ

このエントリーをはてなブックマークに追加 はてなブックマーク - [Tizen][Jenkins]TizenネイティブアプリをJenkinsでビルドした時のメモ

Tizenネイティブアプリ(C++)のビルドをUbuntuのJenkinsでビルド出来るようにした時のメモを記載します。

結論から言うとEclipse CDT Headless build機能を利用する事で簡単に出来ました。(その結論まで辿り着くのに時間が掛かったけど。。。。)

また、上記での運用の場合、.project及び.cprojectファイルもあわせてリポジトリにコミットする事でEclipse(TizenIDE)での設定(平行ビルドやincludeするプロジェクトなどなど)をそのまま使え、新たにmakefile作成ようにシェルを作成しなくても良いのがとても楽です。

環境は以下の通りとなります。

  • Ubuntu 12.10
  • TizenSDK 2.2

また、私の環境では以下のように運用しています。

  • 30分ごとにリポジトリをポーリングし、更新があれば再ビルド
  • ビルドによってtpkまで作成する
  • ビルドの成功可否をIRCで通知
  • Doxygenでドキュメント生成
  • Cppcheckによる静的解析

なお、実施の際には以下を参考にさせて頂きました。

JenkinsでEclipse CDT (C++) プロジェクトをビルドする

C言語/C++でJenkins実践入門してみるよ

目次

  1. UbuntuへのTizenSDKインストール
  2. UbuntuへJenkinsのインストール
  3. Xvfbのインストール
  4. JenkinsでEclipse Headless Build
  5. tpk作成スクリプト作成
  6. Jenkinsプラグインの導入

1.UbuntuへのTizenSDKインストール

Tizenの公式サイトに記載の通り実施します。 java.lang.NoClassDefFoundError: Could not initialize class org.eclipse.swt.widgets.Displayというエラーが出る事がありますが、対応方法は

UbuntuにTizenをインストールする際に「java.lang.NoClassDefFoundError: Could not initialize class org.eclipse.swt.widgets.Display」というエラーが出た場合

として以前のエントリに記載したのでご確認ください。 上記以外は特に点はないかと思いますので、詳細は省きます。

インストール後、TizenIDEが利用できる所までを確認してください。

2.UbuntuへのJenkinsのインストール

以下のコマンドでOK。

sudo apt-get install jenkins

あとはブラウザでJenkinsにアクセスし、適当な名称でジョブを追加します。

3.Xvfbのインストール

Eclipse Headless Buildをコマンドラインから実行する場合に、Xvfbがないとエラーが出るのでインストールします。

>sudo apt-get install xvfb

Xvfbの起動起動及び停止はJenkinsのXvfb Pluiginを利用する事でプラグイン側で自動でやってくれるので、今回はそれを利用します。

Jenkisnのプラグイン管理から上記プラグインをインストールして、パスを設定します。 その後、予め作成したジョブの設定でXvfbに関する設定にチェックを入れればビルド開始時にXvfbの起動を行い、ビルド終了時にXvfbの停止を行ってくれます。

上記を利用しない場合には以下のようなコマンドで実行可能なので一応メモっておきます。

Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
export DISPLAY=:99

4. JenkinsでEclipse Headless Build

いよいよHeadless Buildを利用してビルドします。 Jenkinsのシェル実行の箇所で以下のように記載します。

# move workspace
cd ../
# headless build
/home/toshihirock/tizen-sdk/ide/eclipse -data workspace --launcher.suppressErrors -nosplash -application org.eclipse.cdt.managedbuilder.core.headlessbuild -import Utility -build Utility/Debug

上記例ではUtilityというネイティブプロジェクトをDebugプロファイルでビルドしています。

  • /home/toshihirock/tizen-sdk/ide/eclipse→TizenIDE(Eclipse)の場所を指定。Windowsの場合、eclipse.exeを指定。Macの場合、TizenIDE.app/Contents/MacOS/TizenIDEを指定。
  • -data workspace→workspaceを指定。
  • –launcher.suppressErrors→ポップアップ画面を抑制し、メッセージをコンソールへ出力する。おまじない。
  • -nosplash→スプラッシュ画面抑制。おまじない。
  • -application org.eclipse.cdt.managedbuilder.core.headlessbuild→headless buildを指定。おまじない。
  • -import→Utility ビルド対象のネイティブプロジェクトを指定
  • -build→Utility/Debug Debugビルドを実施。

上記を実行すると.project及び.cprojetの設定に従い、makefileの生成、実行を自動で実施し、ビルドを行います。 (TizenIDEでプロジェクトを右クリック→Build Projetと実行した場合と同じ挙動)

上記実行後、Utility/Debugフォルダが作成され、ビルドがうまくいけばexeファイルの作成が確認できます。

5.tpkファイルの作成

ビルドを行う事でexeファイルは作成できますが、最終的にアプリとして動作させる為にはネイティブアプリの場合にはtpkにパッケージングする必要があります。

上記はTizenから提供されるnative-packagingコマンドを利用します。

コマンドは$TIZEN_SDK_HOME/tools/ide/bin配下に存在します。

なお、tpk作成時の設定ファイル(build_data)については上記と同じ場所に存在するnative-genコマンドを利用して事前に作成します。

cd workspace/Utility
/home/toshihirock/tizen-sdk/tools/ide/bin/native-gen makefile -t app

上記でCommandLineBuildフォルダが作成され、その中にbuild_dataという設定ファイルが作成されるので、適当な場所にコミットします。 (native-genやnative-makeコマンドを利用してビルドも出来ますが、バグっぽいのがあってうまく出来ない事があったので今回はその方法を利用していません。)

また、もし、証明書(p12)を作成していない場合には、予め作成してこちらも適当な場所にコミットします。

これで準備ができたので、native-packaginコマンドを利用してtpkを作成するシェルを作成します。

# Debugフォルダに移動
cd workspace/Utility/Debug
# build_dataをDebugフォルダに移動
cp ../build_data .
# パッケージング
/home/toshihirock/tizen-sdk/tools/ide/bin/native-packaging -ak ../../ryan.p12 -ap mypassword

これで成功すればtpkファイルがDebugフォルダに作成されます。

-akオプションで証明書の場所を指定し、-apコマンドで証明書のパスワードをしております。 各コマンドの詳細はTizenの公式サイトをご確認下さい。

6.Jenkinsプラグインの導入

一応、これでビルドからtpk作成までをJenkisnのジョブとして実行できますが、せっかくなので便利だったJenkinsプラグインもこちらに記載します。(詳細は省きます)

  • Cppcheck Plugin:C++の静的解析が可能です。かなり便利!
  • Doxygen Plugin:連携させておくとDoxygen形式のドキュメントが見れます。
  • IRC Plugin:ビルドの正否をIRCで通知できます。コミットログも合わせてPOSTしてくれるのが意外と便利。
  • Task Scanner Plugin:TODOを集計できます。

2013年8月4日日曜日

[Tizen]ネイティブアプリ開発をコマンドラインで実施する為のメモ

このエントリーをはてなブックマークに追加 はてなブックマーク - [Tizen]ネイティブアプリ開発をコマンドラインで実施する為のメモ

Tizenでは基本的にIDEを利用してソースコードのビルドやパッケージングが出来ますが、IDEを利用せず、コマンドラインでも実施可能なので、そのやり方について記載します。

  1. 利用準備
  2. プロジェクトの作成
  3. makefileの作成
  4. makefileの実行
  5. tpkファイルの作成
  6. tpkファイルを端末(エミュレータ)にインストール
  7. tpkを実行させる

確認した際のTizenSDKは2.2で、OSはMacOSXとなります。

なお、詳細なコマンドオプションなどについては公式ドキュメントのCommand Line Interfaceという欄に記載があります。

利用準備

利用する為にはTizenSDKのインストールが必要となります。 インストール後、コマンドにパスを通す事で利用が出来ます。 私の場合、TizenSDKはhome配下に配置したので以下のようにました。

vi .bashrc
# export Tizen CLI Tools
export PATH=$PATH:/Users/toshihirock/tizen-sdk/tools/ide/bin

プロジェクトの作成

native-genコマンドを利用する事で新規にTizenプロジェクトが作成できます。 例えば、Helloというプロジェクト名、テンプレートでEmptyApplication(起動は可能だが、白い画面が出るのみ)を選ぶ場合には以下のコマンドとなります。

native-gen -n Hello -s empty
Creating a project: Hello...
A project was created successfully in /Users/toshihirock/tizen_workspace/Hello 
To build a project, run native-make in /Users/toshihirock/tizen_workspace/Hello/CommandLineBuild.

上記によってカレントディレクトリにHelloというフォルダが作成され、その配下にテンプレートのコードや設定ファイルが存在します。

-nでプロジェクト名称、-sでテンプレートを選択しています。(その他オプションもありますが、割愛) 詳細なオプションはマニュアルを確認頂ければと思います。

IDEでプロジェクトを作成した時との違いとして、プロジェクト配下にCommandLineBuildというコマンドラインでビルドなどを行う為のフォルダが作成されます。

makefileの作成

デフォルトのソースコードに対応したmakefileはCommandLineBuildフォルダ配下に存在しますが、ソースコードが追加、削除になった場合、makefileを修正する必要があります。

上記についてはプロジェクト作成時同様にnative-genコマンドを利用する事で、makefileのみ更新する事が出来ます。(ただし、現状はTizenのバグなのか分かりませんが、src直下のコードのビルドしか対応しておらず、srcの下にさらにフォルダがある場合には正しいmakefileが作成されないようでした。。。)

先ほどのHelloプロジェクトのmakeifleを再作成する場合、以下のようにします。

cd Hello
native-gen makefile -t app
A makefile was created successfully in /Users/toshihirock/tizen_workspace/Hello/CommandLineBuild.
To build a project, run native-make in /Users/toshihirock/tizen_workspace/Hello/CommandLineBuild.

上記によってmakefileが再作成されます。(既にmakefileが存在する場合でもOKです)

-tオプションでプロジェクトの種類を指定します。

  • app
  • static
  • shared

なお、TizenIDEでプロジェクトを作成したが、CLI用のmakefileを作成したい場合、IDEで

  • 対象のプロジェクトを右クリック→Generate Command Line Configuration

でCommandLineBuildフォルダ配下のファイルを作成する事も可能です。

makefileの実行

makefileの実行はCommandLineBuildフォルダに移動し、native-makeコマンドを利用して実行します。

cd CommandLineBuild
native-make

成功するとCommandLIneBuild配下にexeファイルが作成されます。

tpkファイルの作成

Tizenのネイティブアプリは.tpkというファイルにパッケージングする必要があります。 上記についてはnative-packagingコマンドを利用します。 なお、利用の際に証明書の場所及びパスワードについて指定して実行します。

native-packaging -ak /Users/toshihirock/tizen-sdk/tools/certificate-generator/ryan.p12 -ap mypassword

-akオプションでは証明書のパスを指定し、-apオプションで証明書のパスワードを設定しています。 上記実行後、CommandLIneBuild配下にtpkファイルが作成されます。

tpkファイルを端末(エミュレータ)にインストール

native-installコマンドを利用する事でエミュレータにtpkをインストールできます。

native-install -p vqZpHSuVeq-1.0.0-i386.tpk

-pオプションでインストール対象のtpkファイルを指定しています。 また、上記はエミュレーターが一つのみ起動している場合のコマンドとなります。

端末がないので分かりませんが、端末を接続し、エミュレーターも起動している場合にはどちらにインストールするか指定する必要があります。その場合には-sオプションを利用してserial numberを指定する必要がありそうです。

tpkを実行させる

native-runコマンドを利用する事でtpkを実行できます。

native-run -p vqZpHSuVeq

-pオプションでパッケージ名称を指定することでエミュレーターでアプリが起動する事を確認できます。

最後に

native-uninstallnative-debugというコマンドも存在しますが、調査しきれなかったので割愛します。。。。

2013年7月26日金曜日

[Tizen]UbuntuにTizenをインストールする際に「java.lang.NoClassDefFoundError: Could not initialize class org.eclipse.swt.widgets.Display」というエラーが出た場合

このエントリーをはてなブックマークに追加 はてなブックマーク - [Tizen]UbuntuにTizenをインストールする際に「java.lang.NoClassDefFoundError: Could not initialize class org.eclipse.swt.widgets.Display」というエラーが出た場合
Ubuntu12.10にTizen2.2をインストールしようとしたら、binファイル実行時に
java.lang.NoClassDefFoundError: Could not initialize class org.eclipse.swt.widgets.Display
というエラーが出てインストールに失敗した。
この場合、エラーの通りSWTのクラスが見つけられていないのでswt.jarをJavaのlib/extに配置すればOK。

SWTのサイトからLinux用のZIPファイルをダウンロードするとswt.jarがあるのでこちらを配置。Java7の場合は以下に配置した。
/usr/lib/jvm/java-7oracle/jre/lib/ext
上記で解決する。

2013年7月14日日曜日

[Tizen]TizenでHosted Web applicationsを作ってみる

このエントリーをはてなブックマークに追加 はてなブックマーク - [Tizen]TizenでHosted Web applicationsを作ってみる

Tizenでは大きく分けて以下の2つのWebアプリの提供方法があります。

  • Packaged Web applications
  • Hosted Web applications

ざっくりいうとPackaged Web applicationsはアプリ内(.wgt)にHTML,CSS,JavaScriptを配置して動作するのに対し、Hosted Web applicationsでは外部のサーバーにHTML,CSS,JavaScriptなどを配置させ、アプリから上記のサーバーにアクセスする事で動作します。

Hosted Web applicationsは上記で記載したようにアプリを起動した後にどのURLを表示させるかをconfig.xmlに以下のように記載します。

<tizen:content src="http://your_hosted_app_url"/>

your_hosted_app_urlは適宜変更して下さい。 これだけでOKです。

で、動作確認なのですが、Tizen Web SimulatorだとTizenSDK2.1では動作しません!

なので、Tizenのエミュレーターで動作確認しましょう! こちらだと上記のやり方でアプリ起動後、指定したURLを表示する挙動が確認できます。

2013年7月13日土曜日

Tizen Web Application Checkerを試してみた

このエントリーをはてなブックマークに追加 はてなブックマーク - Tizen Web Application Checkerを試してみた

Tizen Web Application Checkerなるものがあると知った。

TizenのWebアプリケーションとして作成したものがルールに従っているかチェックしてくれるツール、と。

とりあえず試してみる。

公式

Tizen Web Application Checker User Guide

対応OS

  • Linux(Ubuntu)
  • Windows
  • MacOSX

今回はMacOSXで確認。

準備

Nodeのv0.8より大きいバージョンのものをインストールしておけと。 WindowsだとNode入れるときにPythonが必要みたいでそこは注意しろと。

でパスを通しておけと。

$node -v
v0.10.11

こんな感じでパスが通っていればOK。

ダウンロード(インストール)

公式にリンクがあります。(リンク切れしていれば公式から落としてください)

Tizen Web Application Checker

ZIPがダウンロードできるので、解凍。

解凍したフォルダ名をtizen-web-app-checkerとします。

以下でバージョンが取得できるか確認。(tizen-web-app-checkerのパスは適宜変更)

$node ~/tizen-web-app-checker/bin/tizen-web-app-checker.js -V
1.0

使ってみる

TizenIDEからサンプルで作成出来るWebアプリでどんな感じなるか、確認。 Webアプリケーションは作成しビルドすれば、.wgtというファイルが出来るのでそれを利用します。 利用方法は以下のようにします。単純にさっきのコマンドの引数にwgtのパスを渡せばOK。

$node ~/tizen-web-app-checker/bin/tizen-web-app-checker.js ~/tizen_workspace/TizenWebApp/TizenWebApp.wgt 

start checking according to Tizen 2.1 compliance specification
Package checker started...
 Checker finished.
Security checker started...
Generating html report...
All tests completed.
Results report: /Users/toshihirock/tizen-web-app-checker/TizenWebApp.html

最後の行でレポート出力結果のHTMLをどこに出力したか表示されるので開きます。(tizen-web-app-checker配下に出力されるっぽい)

$open /Users/toshihirock/tizen-web-app-checker/TizenWebApp.html 

今回の奴はとくにNGのポイントはなく成功。

jQueryMobileのサンプルアプリ作ってこのツールで確認するとこんな感じでエラーとか検出してくれました。

2013年7月10日水曜日

「Tizenネイティブアプリ開発ことはじめ」というタイトルにて勉強会で発表してきました

このエントリーをはてなブックマークに追加 はてなブックマーク - 「Tizenネイティブアプリ開発ことはじめ」というタイトルにて勉強会で発表してきました

タイトルの通り、Tizenネイティブアプリ開発ことはじめという事でWebプラットフォーム勉強会にて発表させて頂きました!


あまり人前で話すのは得意でなく、当日も色々操作ミスしたりしてしまったのですが、助けてくださる方がいらっしゃって何とか終える事が出来ました。

半分勢いもあって応募したのですが、良い経験になりましたっ!

2013年7月2日火曜日

[Tizen]TizenIDEでDoxygenコメントの補完

このエントリーをはてなブックマークに追加 はてなブックマーク - [Tizen]TizenIDEでDoxygenコメントの補完
デフォルト設定のTizenIDEだとDoxygenコメントの補完がされない。(メソッドで/**とタイプした際に@param,@returnなどの補完が行われない)

上記についてはPluginなしで以下の設定変更で対応可能。

  • Preferences→c++→Editor→Documentation tool commentsで選択出来るセレクトボックスでDoxygenを選択。


以上で完了っす。

2013年6月24日月曜日

[Tizen]Tizenネイティブアプリ開発でのUnitテストの実施

このエントリーをはてなブックマークに追加 はてなブックマーク - [Tizen]Tizenネイティブアプリ開発でのUnitテストの実施

Tizenネイティブアプリ開発時のUnitテストについて試してみたのでメモ。

Tizenのネイティブアプリ開発ではC++での開発となりますが、テストはどうするのかというと標準でGoogle C++ Testing Frameworkが同梱されており、公式ドキュメントでもこれを使うような記述があるのでこれを利用するのが一般的ではないかと思われます。

Unit Test Tool

上記リンクからTizen Native App Programing→IDE and Tools→Unit Test Toolと辿るとTizen公式ドキュメントが確認できます。

今回の例ではサンプルアプリにクラスを追加し、そのクラスに対してテストを行ってみます。 手順は以下の通りです。

  1. テスト対象プロジェクト作成(サンプルアプリ)
  2. テストプロジェクトの作成
  3. テストプロジェクトの編集
  4. テストプロジェクトの実行

なお、公式ドキュメントにテストの項目の欄で以下の記述があるため、注意が必要ではあります。

  • The unit test tool is designed to support only functional testing.
  • The unit test tool is not an OSP-based application. Therefore, certain methods related to the OSP application framework, such as the methods of the Tizen::Base::String class, can behave incorrectly.

超適当な意訳

  • functionテストのみがサポートですよー。
  • このUnit Test toolはTizen用のテストツールって訳じゃないよ。なので、Tizen::Base::Stringクラスとかいくつかのメソッドなどは誤った動作するかと思われます。

ま、まじでか。 とか思って試しにTizenのStringを利用したテストコード書いてみましたが、一応大丈夫でした。 保証はできないってことか、な。

確認環境など

  • MacOSX 10.8.4
  • TizenSDK2.1(IDEやSDKなどはインストール済み)

1.テスト対象プロジェクト作成(サンプルアプリ)

まずはテスト対象のHellWorldプロジェクトをTizenIDEを利用して作成します。

  • File→New→Others
  • Tizen→Tizen Native Project
  • Templateタブを選択→Tizen Native→Form-based Application→With SceneManagerを選択。Project Nameは任意の名前でOKですが、本例ではHelloWorldとします。

これでとりあえずプロジェクトができます。

次にUtilクラスを追加します。

とりあえずこんな感じでメソッドを2つ作ってみました。(C++初心者なので書き方がまずいかもしれませんが、とりあえず許して下さい。。。)

Util.h

#ifndef UTIL_H_
#define UTIL_H_
#include <FBase.h>

class Util {
public:
    int Sum(int x, int y) ;
    void AppendWorld(Tizen::Base::String& base);
};


#endif /* UTIL_H_ */

Util.cpp

#include "Util.h"

int Util::Sum(int x, int y) {
    return x + y;
}

void Util::AppendWorld(Tizen::Base::String& base) {
    base.Append("World!");
}

Sum関数では引数に渡した2つの引数の加算を行った結果を返却します。

AppendWorld関数では引数に渡したTizen::Base::Stringクラスの参照引数を利用してAppendメソッドを呼び出して、引数に渡された文字列の末尾に“World!”という文字列を追加します。

今回は上記2つのメソッドに対してそれぞれテストコードを書いてみます。

2.テストプロジェクトの作成

Tizenでテストを行う場合、テスト対象のプロジェクトとは別に新規にテスト用プロジェクトを作成する必要があるようです。 以下の方法で作成を行います。

  • File→New→Others
  • Tizen→Tizen Native Unit Test Project
  • Select the Tizen Project for testの箇所でHelloWorldを選択。

これでHelloWorldプロジェクのテストプロジェクトの完成です。 デフォルトで以下のようなテンプレートテストコードが作成されます。

HelloWorldTest.cpp

include "tizenx.h"
#include "Util.h"
#include "HelloWorldPanelFactory.h"
#include "HelloWorldMainForm.h"
#include "HelloWorldFrame.h"
#include "HelloWorldFormFactory.h"
#include "HelloWorld.h"
#include "AppResourceId.h"

#include <gtest/gtest.h>

class TestSuite : public testing::Test
{
    protected:
    // virtual void SetUp() will be called before each test is run.
    // You should define it if you need to initialize the variables.
    // Otherwise, you don't have to provide it.
    virtual void SetUp()
    {

    }
    // virtual void TearDown() will be called after each test is run.
    // You should define it if there is cleanup work to do.
    // Otherwise, you don't have to provide it.
    virtual void TearDown()
    {

    }
};

// When you have a test fixture, you define a test using TEST_F.
// Otherwise, you define a test using TEST.
TEST_F(TestSuite, test01)
{
    ASSERT_TRUE(true);
}

TEST_F(TestSuite, test02)
{
    ASSERT_TRUE(false);
}

先ほど作成したUtilクラスのヘッダファイルもincludeされているのでテストコードが追加できそうです。

3.テストプロジェクトの編集

HelloWorldTest.cppにSum関数、AppendWorld関数のテストコードに以下のように追加(編集)します。 なお、test02はデフォルトだと実行するとNGとなってしまうので、こちらも変更します。

TEST_F(TestSuite, test02)
{
    ASSERT_TRUE(true);
}
TEST_F(TestSuite, test03)
{
    Util *p = new Util();
    ASSERT_EQ(3, p->Sum(1, 2));
    delete p;
}

TEST_F(TestSuite, test04)
{
    Util *p = new Util();
    Tizen::Base::String hello = Tizen::Base::String("Hello");
    Tizen::Base::String helloworld = Tizen::Base::String("HelloWorld!");
    p->AppendWorld(hello);

    ASSERT_EQ(helloworld, hello);
    delete p;
}

test03ではSum関数の引数に1と2を渡し、結果で3がかえってくる事を確認しています。

test04ではHelloという文字列のTizen::Base::Stringクラスを作成し、AppendWorld関数を利用する事で“HelloWorld!”という文字列になる事を確認しています。

なお、利用しているGoogle C++ Testing Frameworkについては以下の翻訳サイトを参考にさせて頂きました。(まだ全然読めてないですが)

Google C++ Testing Frameworkをはじめよう

4.テストプロジェクトの実行

いよいよテストを実行します。 テストの実行及び結果の確認はTizenIDEで実施できます。

テスト対象のプロジェクトのビルドをしてからテストコードの存在するプロジェクトをビルドします。

  • HelloWorld→右クリック→Build Project
  • HelloWorldTest→右クリック→Build Project

なお、先にHelloWorldTestの方をビルドすると以下のような先にテストする方のプロジェクトしろよ的なメッセージが出ます。その場合、メッセージの通り先にテスト対象のビルドを実施し、その後再度テストプロジェクトのビルドをすればOKです。

次にエミュレーターを起動します。 個人的にはエミュレーターなしでやりたかったのですが、IDEから実行するときは必要だったのでやっておきます。

さてこれで準備がすべて終わったのでいよいよテストを実行します。

  • HelloWorldTest→右クリック→Run As→Tizen Native Unit Test Application

これで実行されるのでしばし待ちます。

結果はIDE上のTest Resultで確認できます。

また、上記左にあるTest Exploerを利用すると特定のテストコードのみの実行ということも可能です。

Tips

設定を行う事で以下が可能なようですが未確認。

  • HelloWorldTest→右クリック→Run As→Run Configurations

以下設定可能項目。
  • Run Disabled Tests
  • Shuffle Tests
  • Don’t Print Elapsed Time
  • Generate and XML Report

Jenkinsとかとも連携さたいので今後はCLIからの実施方法なども確認したい。

2013年6月17日月曜日

[Tizen]Tizenネイティブアプリのビルドでccacheを利用してみる

このエントリーをはてなブックマークに追加 はてなブックマーク - [Tizen]Tizenネイティブアプリのビルドでccacheを利用してみる

前エントリーでC++の平行ビルドのやり方について書きましたが、もう一つのコンパイラキャッシュを利用してビルド時間を短縮する方法を記載します。具体的にはccahceというツールを利用します。 なお、利用するのがキャッシュなので1回目のビルドは早くならないみたいです。ご了承下さい。

また作業実施にあたり、以下を参考にさせていただきました。

ビルドの待ち時間を減らす - ツール編

ccacheのインストール

ccacheをインストールします。 Macの場合にはhomebrewでインストールできます。Windowsの場合、ビルドするための環境(cygwinなど)が必要なようです。。。なお、こちらが公式サイトとなります。

$brew install ccache

Ubuntuなら以下でも大丈夫なようです。(確認はしてません)

$sudo apt-get install ccache

後で利用するのでパスも確認します。

$which ccache
/usr/local/bin/ccache

ccacheの利用

TizenのC++コンパイラはclang++というのを使っているみたいで、そのコマンドを利用する際にccacheも利用してね、という設定を行います。

  • 対象のプロジェクトで右クリック→Properties

  • C/C++ BuildでGenerate Makefilesにチェックが入っている事を確認

  • Settings→C++ Compiler

Commandの箇所を変更したいのですが、変更しても反映されないので(バグか?)ちょっと微妙な気もしますが、Command line patternの箇所を変更します。

  • 変更前→${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
  • 変更後→/usr/local/bin/ccache clang++ ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}

また、上記だけでなくC++ Linkerも同じように変更します。

  • 変更前→${COMMAND} ${OUTPUT_FLAG}${OUTPUT_PREFIX}${OUTPUT} ${INPUTS} ${FLAGS}
  • 変更後→/usr/local/bin/ccache clang++ ${OUTPUT_FLAG}${OUTPUT_PREFIX}${OUTPUT} ${INPUTS} ${FLAGS}

ちょっと、いやかなりださい気もしますが、commandの箇所が変更できないので仕方ない。。。

ビルドしてみる

対象のプロジェクトを右クリックしてビルドしてみます。 で、Consoleで上記設定が反映されているかを確認します。

/usr/local/bin/ccache clang++ -I"pch" -D_DEBUG ...(以下略)

上記の通り、コンパイルの箇所でccacheを利用したコマンドへの変更ができているようです。

また、以下のコマンドを実行するとどれぐらいキャッシュが有効だったかなどを確認できます。

$ ccache -s
cache directory                     /Users/toshihirock/.ccache
cache hit (direct)                    54
cache hit (preprocessed)               0
cache miss                            19
called for link                        9
files in cache                        34
cache size                          14.7 Mbytes
max cache size                       1.0 Gbytes

こんな感じで結果がでます。私はHelloWorldプログラムでの確認なのであんまり効果がないっぽいですが、大きなプロジェクトであれば、効果があるかと思っております。 実際に早くなっているかについては計測していないので分かりませんが、時間とやる気があればどこかで。

2013年6月16日日曜日

[Tizen]Tizenのネイティブアプリで平行ビルドしてみる

このエントリーをはてなブックマークに追加 はてなブックマーク - [Tizen]Tizenのネイティブアプリで平行ビルドしてみる

Tizenのネイティブアプリ開発はC++で実施しますが、TizenIDEでビルドする際に平行ビルドを有効にする方法のメモ。

平行ビルドによってビルド時間が短縮できるかはソースの構成などに依存するっぽいですが、C++のビルド時間短縮の常套手段っぽいのでとりあえずやっておきます。

手順

  • 対象のプロジェクトを選択して右クリック→Properties。

  • C/C++ Build→Behaviourタブをクリック。

  • Use parallel buildにチェックを入れる。

  • Use optimal jobs numberもしくはUse parallel jobsと数字を入れる。

例えばUse parallel jobsにチェクをして、数字に2と入れるとビルドの際にmake -j 2 となっており、平行ビルドが実行されている事がTizenIDEのConsoleで確認できます。

/Users/toshihirock/tizen-sdk/tools/smart-build-interface/bin/sbi action tizen-emulator-2.1.native_llvm31.i386.cpp.app -- make -options="-j2 all" -cliprojpath="" -clisdkpath="" -cliunitprojpath="" -cliappid="" 
Checking prerequisite...
Checking make... ok
Building file: ../inc/tizenx.h

平行ビルド数はPCのCPU数コア数より少し多い(?)ぐらいらしいです。。よく分からんけど。

私の環境だとUse optimal jobs numberにすると並列ビルドになりませんでした。サンプルでビルドしているのがHelloWorldのサンプルアプリだからなのかもしれませんが。

2013年6月10日月曜日

[Tizen]Tizenアプリのログ出力方法とかについてドキュメント確認してみた

このエントリーをはてなブックマークに追加 はてなブックマーク - [Tizen]Tizenアプリのログ出力方法とかについてドキュメント確認してみた

TizenのドキュメントのDebugging Macros(ログとかデバッグに関する記述)について確認したのでメモ。 なお、PCのスペックが低くて、実際確認ほぼできず、ドキュメントを意訳した内容となります。

確認はTizenSDK2.1となります。

ドキュメントの詳細は公式サイトのDebugging Macrosを参照ください。

LogViewの表示

以下の操作でTizenIDEより表示出来ます。

Window→Show View→Log

ほとんどAndroidの奴と一緒っぽい感じ。

  • ログレベルによるフィルタリング
  • タグによるフィルタリング
  • ログのエクスポート
  • ログのクリア

とか出来るっぽいです。

ログの書き方

何やら大きく分けて4種類も有るみたい。

  1. Log Macros
  2. Try Macros
  3. Assert Macros
  4. Secure Log Macros

1.Log Macros

すごく普通のログ。

ログレベル指定

ログレベル(info,debug,error)を呼び出すメソッドによって切り替え、引数には表示するログメッセージを設定。

以下記述例。

AppLog("Initialization successful.");

また、以下に各ログレベルでの記述方法を記載します。

  • AppLog(message)
  • AppLogDebug(message)
  • AppLogException(message)

一番上のAppLogはInfoレベルで、AppLogDebugがDebugレベル、AppLogExceiptionがErrorレベルでの出力となります。

条件付きログ出力

第一引数(expression)の条件式がtrueの場合のみログ出力する事も出来る。

以下記述例。

int initVal;

// If initVal is greater than 0, print the info message to the console
AppLogIf(initVal > 0, "initVal is %d.", initVal);

上記のように記載すると変数initvalが0より大きい場合のみログを出力する事が出来ます。 また、以下に各ログレベルでの記述方法を記載します。

  • AppLogIf(expression, message)
  • AppLogDebugIf(expression, message)
  • AppLogExceptionIf(expression, message)

タグ付け

フィルタリングしやすいようにタグを付けてログ出力も出来る。

以下記述例。

AppLogTag("MyTag", "Initialization successful.");

また、以下に各ログレベルでの記述方法を記載します。

  • AppLogTag(tag, message)
  • AppLogDebugTag(tag, message)
  • AppLogExceptionTag(tag, message)

2.Try Macros

条件式結果によってhogeしてからログ出力…みたいな事が出来たりします。なお、ログレベルは一律でError

後述するAssert Macrosとの違いとしてこちらのTry MacrosではプロセスKillはしないみたいです。

TryCatch(condition, expressions, message)

実例を見た方が分かりやすいので、以下記述例。

const A*
MyClass::DoSomething(const wchar_t* pValue)
{
    result r = E_SUCCESS;
    // Do something

// If pValue is null, print "[E_INVALID_ARG] The pValue is null." to the console, 
// execute the expression "r = E_INVALID_ARG", and move to CATCH
TryCatch(pValue != null, r = E_INVALID_ARG, "[E_INVALID_ARG] The pValue is null."); 

SetLastResult(E_SUCCESS);

return _pValue;

CATCH:
  SetLastResult(r);

  return null;
}

英語で書いてある通りですが、

  1. pValueがnullか判断。(conditionの条件式)
  2. pValueがnullの場合、ログで[E_INVALID_ARG] The pValue is null.とErrorレベルのログを出力。
  3. 変数rに定数E_INVALID_ARGを代入。
  4. Catch構文に遷移。

という流れみたいです。

TryReturn(condition, returnValue, message)

条件式(condition)で結果がfalseの場合、messageを出力して、returnValueに記載された値を返却する。

TryReturnVoid(condition, message)

条件式(condition)で結果がfalseの場合、messageを出力して、returnするけど値は設定しない(void)と。

TryLog(condition, message)

条件式(condition)で結果がfalseの場合、messageを出力してその後の処理を継続。(returnしない)

タグ付け

上記それぞれのメソッドで引数が一つ増えてタグを付けるものがありますが、説明は省略。

3.Assert Macros

条件式(condition)の内容がfalseの場合、なんとプロセスkillするそうです!

リリースビルドではやめてね、って書いてあります。

AppAssert(condition)

条件式(condition)で結果がfalseの場合、現在のプロセスをkillする。(ログ出力なし)

AppAssert(condition, message)

条件式(condition, message)で結果がfalseの場合、messageの内容をエラーレベルのログとして出力し、現在のプロセスをkillする。

4.Secure Log Macros

基本的にLog Macros,Try Macrosと似たメソッドがあるが、以下の点が違うようです。

  • 「_SECURE_LOG」を定義していればログを出力するし、なければコンパイルタイミングで消す。
  • 出力ログ文字列の先頭にprefixとして[SECURE_LOG]を追加

一つの目の点が大きな違いですね。(すいません、C++があまり分からず、_SECURE_LOGを定義、というのが具体的に何をすれば良いのか分かってません。。値はいれず、単純に宣言すればよい?)

という事で以下はメソッドのみ記述。

  • AppSecureLog(message)
  • AppSecureLogDebug(message)
  • AppSecureLogException(message)
  • AppSecureLogTag(tag, message)
  • AppSecureLogDebugTag(tag, message)
  • AppSecureLogException(message)
  • AppSecureLogTag(tag, message)
  • AppSecureLogDebugTag(tag, message)
  • AppSecureLogExceptionTag(tag, message)
  • SecureTryCatch(condition, expressions, message)
  • SecureTryReturn(condition, returnValue, message)
  • SecureTryReturnVoid(condition, message)
  • SecureTryLog(condition, message)
  • SecureTryCatchTag(tag, condition, expressions, message)
  • SecureTryReturnTag(tag, condition, returnValue, message)
  • SecureTryReturnVoidTag(tag, condition, message)
  • SecureTryLogTag(tag, condition, message)

2013年6月8日土曜日

第1回 Build Insider OFFLINE勉強会のメモ

このエントリーをはてなブックマークに追加 はてなブックマーク - 第1回 Build Insider OFFLINE勉強会のメモ

Blogを書くまでが勉強会!

という事で第1回 Build Insider OFFLINEに参加して来たのでその際のメモ。(間違っているなどの箇所が有れば修正します!)

★JavaScripライブラリーを使い倒そう!(Wingsプロジェクト 安西さん)

1.手間を省こう系

  • jQuery,protorype.js
  • jQueryUIなどのUIライブラリ。Choosen,竹取JS,FullCalendar,jqPlot(グラフ)など
  • Twitter Bootstrap
  • jQueryMobile

使いまくると読み込むファイル数が多くなり、表示速度が遅くなるので注意。

高速化のポイント

  • ファイル数を少なく
  • CSSスプライト
  • JavaScriptの読み込みタイミング
  • ブラウザキャッシュ

2.言語特性補う系

  • CoffeeScript
  • TypeScritp

3.フレームワーク系

  • Backbone.js
  • Angular.js
  • Knockout.js
  • Ember.js
  • Spine.js

4.ゲーム系

新人教育にゲーム系フレームワーク利用させるのはオブジェクト指向の理解としても有効だった。

  • enchant.js
  • Unity

5.サーバー系

  • Node.js
  • Express.js

6.テスト系

テストフレームワーク

  • Qunit
  • Mocha
  • Jasmine

テストを書いてからメソッドを書く。→TDD形式。 ユーザーからの振る舞い→BDD形式。

  • JSTestDriver
  • sinon.js

静的解析

  • JSHint
  • Jscoverage

JSテストでLinux,Mac,WindowsをVMで立ててJenkinsとJsTestDriverを利用した。

★3つのMVC系人気フレームワーク、Backbone.js/AngularJS/Knockout.js

Backbone.js(LINE株式会 清水さん)

  • Angluar.jsはフルスタック
  • MVCモデル
  • BackboneにはPluginなどがある。Utilityも存在。
  • Plugin→backbone relational,backbone forms,marionettejs,backbone boilerplate
  • Angular.jsはPC,モバイルはBackbone.jsの方が使いやすい印象。(Angularはフルスタックだからでかい)
  • BackboneはREST使うとすごく短いコードで書ける。
  • テストはGruntを利用。jasmine,mochaなど。テストコードが書きやすい。
  • Gruntのwatchタスクでファイル変更を監視して、テストコード自動実行みたいなの便利。
  • Grunt notifyで実施したテストでエラーだった場合にMacのNotification(Growl)なども出来て便利。

Angular.js(金井さん)

得意

  • CRUDとか強力。
  • 管理ページ、マイページ作成など得意。

苦手

  • モバイル系は苦手。というかファイルサイズがかなり大きい。
  • ゲームなどのグラフィックの扱い。

テスト

  • Karma

モバイルについて

  • ngMobileというのが追加されてはいるが、現在はフルスタックのため、全ての機能がある。
  • 元からダウンロードするアプリとか(リソースにAngularJSを置く)であればモバイルでも有用。

UI

  • AngularUIなど、色々あるので外部のものを利用するのが良さげ。

Knockout.js(沢渡さん)

  • MVVMパターン
  • 単一のライブラリでjQueryにも依存しない。
  • 他のフレームワークと比べると軽量。
  • Observableとは?Knockout.jsの機能。機能の通り、値が変わったか、などを確認出来る。varで宣言した値が変わった場合などの監視も可能。
  • subscribeで変更された時に通知する先を指定可能。コールバック関数を宣言。
  • ko.computedはobservableと同様に値の監視が出来る。
  • もう一つの大きな機能。バインディングが存在する。

★スマホ向けWebアプリ開発で使えるフロントエンド高速化手法( 株式会社gloops 児玉さん)

基本

  • styleは上に、scriptは下に
  • 画像の形式。もしくは画像をCSSで代用。
  • minify化、キャッシュの利用。
  • CSSスプライトの利用。
  • DataURIスキームを使う。

CSSスプライト

  • HTTPリクエストが減る。一回に。
  • デメリットとしては画像の表示は遅くなる。

DataURIスキーム

  • HTTPリクエスト無し
  • CSSスプライトより表示処理は早い
  • デメリットとして画像ファイルの容量が大きくなるのでキャッシュが必須。

どの程度まで頑張る?

  • 1秒以内とか目標を。

ページサイズとHTTPリクエスト減らしても遅い場合は?

  • CSSセレクタは右から左へ解釈されるのでそこを考慮すべき。ただし、そこまで改善が見込めない場合も有るので、やりすぎは良くない。
  • 処理が重いCSS。border-image,background-size グラデーション、box-shadow,text-shadowなど。
  • Gooogle Chrome Canaryで設定するとCSSの描画を繰り返す事が出来るので、そこで処理のボトルネックを探す事が出来る。
  • JSでfor文のlengthは変数に入れて回すべき。処理速度の観点から。
  • dom操作するとブラウザ側でスタイルやレイアウトの再計算が行われるので、なるべく少なくすべき。

ユーザー体感速度の高速化

  • 操作出来る部分を先に表示する。例えば画像のレンダリング順番を変える。cssのbackground-imageよりimageタグの方が先にレンダリングされる。
  • touchイベントとmouseイベントは違う。PCはmouseイベントのみ。また、スマホではtouchイベントが早い。
  • touchstart→指が触れて発生。touchhend→ディスプレイから指を離すと発生。

[Tizen]TizenIDEからローカルでTizenドキュメントを参照する方法

このエントリーをはてなブックマークに追加 はてなブックマーク - [Tizen]TizenIDEからローカルでTizenドキュメントを参照する方法

TizenIDEからローカルでTizenドキュメントが参照出来るのでメモ。

TizenIDEを起動して、Help→Help Contentsでブラウザが起動してローカルで参照が出来る。

地味だけど便利っす。

また、TizenSDKのクラス、メソッドなどにhover(マウスを合わせる)するとドキュメントがIDE上で参照出来るのでこれも便利。

2013年6月2日日曜日

[Tizen]Tizen Nativeアプリ(C++)でDoxygen+Graphvizを使ってJavaDoc形式コメント書いてみたり、クラス図継承関係確認してみた話

このエントリーをはてなブックマークに追加 はてなブックマーク - [Tizen]Tizen Nativeアプリ(C++)でDoxygen+Graphvizを使ってJavaDoc形式コメント書いてみたり、クラス図継承関係確認してみた話

TizenのネイティブアプリはC++で書かなければいけなくて、C++でJavaDoc的にソースコードにコメントを書こうと思って、何か良いのないかなーと調べてたら何やらDoxygenでそれ出来るよと。

ちなみにDoxygenですが以下のような特徴が有ります。

  • 対応言語はC++だけでなく、Java、Objective-C、Pythonなどがある。
  • Windows、Mac OS X、Linuxで動く。
  • 出力形式としてHTML以外にXMLやLaTeX、RTFもある。

あとGraphvizも使うとクラス図とそれぞれの依存関係が分かるとかでやってみました。

というか最初に言ってしまうとTizen公式サイトのAPIリファレンスもDoxygen+Graphvizを利用しているっぽかったので、結構デファクトスタンダードなのかもとか思ったり。(C++は全く詳しくない)

参考

なお、実施に当たり、以下のサイトを参考にさせて頂きました。

ソースコードを読むのに Doxygen + Graphviz が便利な件

Doxygen+Graphvizでクラス図を自動生成する

確認方法

本例ではTizenIDEでサンプルテンプレートとして用意されているTizenネイティブアプリのFrom-based Application→With SceneManagerにJavaDocコメントを追記して確認しました。(HelloWorldアプリ)

コメント追加

まず、HelloWrold.cppにJavaDoc形式でコメントを記述します。 なお、詳細なコメント記述形式は以下の公式サイトコードのドキュメント付けが分かりやすいです。

Doxygen、Graphvizのインストール

次にDoxygenのインストールします。Homebrewを利用。

brew install doxygen

Graphvizもインストール。こちらもHomebrewを利用。

brew install graphviz

簡単!

なお、Windowsもそれぞれの公式HPにインストーラーがあって簡単にインストール出来ます。

設定ファイル作成

次にクラス図を作成したいディレクトリに移動し、doxygenコマンドで設定ファイルを作成。

cd tizen_workspace/HelloWorld/
doxgen -g

なお、Windowsの場合、doxygenのインストールが終わるとすべてのプログラムにdoxygen wizardというプログラムがあり、それでどのフォルダのドキュメント作成をするか指定していきます。

上記実行後、カレントディレクトリにDoxyfileというファイルが生成されますので、これを編集して出力するドキュメントの詳細を記述します。私の環境ではとりあえず以下を設定。 オプションの詳細はDoxygenを参照下さい。

# 文字エンコーディング。
DOXYFILE_ENCODING = UTF-8

# 出力するファイルの言語
OUTPUT_LANGUAGE = Japanese

# 再帰的にソースコードを捜索するか。
RECURSIVE = YES

# Graphvizを利用するか
HAVE_DOT = YES

# Graphvizのパス。Homebrewでインストールした場合、PATHが通っているので設定しなくても良い。Windowsの場合、Graphvizのbinフォルダを指定する。
DOT_PATH =  

# LaTexを出力するか。
GENERATE_LATEX = NO

実行

設定が終わったら以下のコマンドでドキュメント出力。

doxygen

見てみる

カレントディレクトリにhtmlフォルダが作成されます。その下にindex.htmlが有るので表示。

open html/index.html

しっかり日本語で表示出来てます。

試しにJavaDocコメントを記載したHelloWorld.cppを見てみます。

おお、良い感じ。しっかり日本語表記も出来てます。

クラス階層を見るとこんな感じ。継承関係が分かりやすく表示されています。

上記画面でクラスをクリックすると該当クラスの詳細に遷移するとかも便利。あと左上の検索バーでクラス検索が出来るのですが、サジェスト検索出来るのも結構嬉しい機能。

おまけ

結構感動してJavaのプログラムにも実行してみましたが、クラス継承関係が図式で表示する事が出来て非常に有用だと感じました。

[Tizen]Tizenエミュレーターを動かそうとしてActive secure profile is not set.Please check the signing configuratons at Preferenceとかエラーで出た場合の対応

このエントリーをはてなブックマークに追加 はてなブックマーク - [Tizen]Tizenエミュレーターを動かそうとしてActive secure profile is not set.Please check the signing configuratons at Preferenceとかエラーで出た場合の対応

TizenSDK2.1系でNativeアプリ、Webアプリ関わらずエミュレーターでTizenアプリを始めて動かそうとすると以下のエラーダイアログが表示される場合が有る。

Active secure profile is not set.Please check the signing configuratons at Preference > Secure Profiles.

エミュレーターにアプリをインストールする際に利用する証明書が設定されていないと表示されるエラーです。Profileで証明書を指定する必要があるので、以下の公式サイトCertificate Generatorの通り証明書を作成します。

TizenSDKをインストールしたディレクトリの配下に証明書作成用のディレクトリがあるので移動。<TIZEN_SDK_HOME>の箇所は自分がTizenSDKをインストールしたディレクトリに置き換えて下さい。

cd <TIZEN_SDK_HOME>/tools/certificate-generator 

Shellを実行(Windowsの場合、certificate-generator.batを実行)

./ certificate-generator.sh

質問が色々出てきますが、とりあえず動けば良いのでOptionalの箇所は何も指定せず(Enterを押すのみ)、それ以外の箇所も公式サイトの例の通り指定。

toshihiro308@Toshihirock-MacBook-Air:~/tizen-sdk/tools/certificate-generator$ ./certificate-generator.sh 
Please enter the country name(optional, two letters): (Enter)

Please enter the state or province name(optional): (Enter)

Please enter the city name(optional): (Enter)

Please enter your name(optional, default is 'author'): (Enter)

Please enter your organization name(optional): (Enter)

Please enter your department name(optional): (Enter)

Please enter your email id(optional): (Enter)

Please enter password for pkcs12 format key certificate: 
mypassword
Please enter alias for generated pkcs12 structure: 
ryan
Please enter file name for storing pkcs12 file (*.p12): 
ryan.p12

上記の通り、実行するとカレントディレクトリにryan.p12というファイルが生成されます。

次にTizenIDEに上記のファイルを利用してね、ということを設定します。 TizenIDEを起動し、

TizenIDE→Preferences→TinzenSDK→Secure Profiles

を選択。

ProfilesのAddを押して適当な名前のProfileを作成します。

Profile ItemsのCerificate pathに先ほど生成したp12ファイルのパスを指定し、PasswordにはPlease enter password for pkcs12 format key certificateで指定したパスワードを記載(上記例ではmypassword)を指定し、OKを選択。

その後はTizenエミュレーターで確認が出来ると思います。

2013年5月27日月曜日

GaiaプロファイルでFirefoxOSを起動してついでにロック画面も変えてみた

このエントリーをはてなブックマークに追加 はてなブックマーク - GaiaプロファイルでFirefoxOSを起動してついでにロック画面も変えてみた

気になったのでやってみました。 手順はツイートの通りですが、一応。

なお、普通(!?)にFirefoxOSのエミュレータ使う場合のやり方(Firefoxにアドオン追加)は[FirefoxOS]WebアプリをFirefoxMarketplaceにFirefoxOS用アプリとして登録した時のメモのエントリを参照ください。

まずはGitHubからGaiaをclone。

git https://github.com/mozilla-b2g/gaia.git

DEBUG=1でmakeする。

cd gaia
make DEBUG=1

完了すると最後に以下のようにprofileの場所が記載されます。

Profile Ready: please run [b2g|firefox] -profile /Users/toshihiro308/git/gaia/profile

プロファイルを指定してFirefoxNightlyを起動。

FirefoxNightly.app/Contents/MacOS/firefox -profile /Users/toshihiro308/git/gaia/profile

起動出来たー!

そういえば、昨日参加したWebプラットフォーム勉強会でホームスクリーンとかロック画面とか変えてみたとかというお話を聞いたような。。。

KEONとPEAKが無くてもFirefox OS開発出来る

ロック画面変えてみましょ!

vi gaia/apps/system/style/lockscreen/lockscreen.css
background: transparent url('./images/mask.png') 50% 50% no-repeat;

上記pngを適当な画像に変えて、再度起動。

とりあえずロックスクリーンをPink Floydにしてみた!

あれこれ何の話だっけ。。。。

2013年5月18日土曜日

Yeomanを使って簡単に今っぽいHTML5Webアプリケーション環境を構築

このエントリーをはてなブックマークに追加 はてなブックマーク - Yeomanを使って簡単に今っぽいHTML5Webアプリケーション環境を構築

Yeoman使えばGrunt,bowerも入るよっ!
YouTubeでChrome+HTML5 Developers Live Japan #4をたまたま見たら、Yeomanを使うとWeb開発で色々便利!という事を知り、早速導入。
なお、上記動画のスライドはつかってみよう!Yeoman。HTML5Webアプリケーション開発を効率化するツールの紹介にありましたが、とても分かりやすいです!
具体的にはYomanは大きく分けて以下によって構成されています。
  • Yo→Scaffold。npmでインストールしたテンプレートに従って、ディレクトリとか最低限必要なファイル群を構成してくれる。
  • Grunt→Build及びタスク実行。CoffeeScript、ビルドしたり、テスト実行したり、特定ファイルの変更監視して、ページの自動ロードしたり。すごいみたい。
  • Bower→HTML、CSS、JavaScript用のパッケージマネージャ。これを使ってjQueryとかBackboneとかのバージョン管理とか出来るみたいで便利そう。
実はどれもしっかり使った事がなくて、説明が曖昧ですいません。。。
個人的にYeomanに惹かれたポイントは以下です。
  • yoというコマンドがなんか良い。
  • インストールが楽。
  • Webアプリケーション構築時にTwitter Bootstrap for SassをYes/Noでインストールできる。
  • GruntでのLiveReloadやばい(ファイル保存でブラウザも自動更新される)
  • Gruntの設定ファイル作成面倒そうだけど、とりあえず動く奴作ってくれる。
  • Webアプリ作成時のテンプレートでBackboneとかAngularとかある。

1.準備

rubyのインストール

私は入っていたので除外。 rvmを利用してバージョン管理しています。 ちなみに1.9.2を利用。

nodeのインストール

最近はnodebrewが良さげみたいですが、僕はnvmインストールしてたのでそれで。0.8より新しいバージョンのnode必要のようです。
nvm ls-remote
nvm install v0.10.11
nvm use v0.10.11
★2013年6月16日修正
node v0.11はbowerのサポートをしていないみたいで、利用するnodeバージョンをnode v0.10に変更しました。

Compassのインストール

何かでインストールしてたので除外。 gemコマンドでもインストール出来るようです。 ちなみに0.12.2を利用。

Gruntのインストール

gruntをインストールしてないとgrunt-cliは動かないみたいなのでインストール。(細かく検証してませんが、必要ないかもしれません。ただ、インストールしてても問題ないはずです。)なお、gruntのバージョンは3.0より新しくする必要があるみたいです。
npm install -g grunt

2.インストール

Yeomanをnpmを利用してインストールします。 コマンドは公式サイトそのままで。
npm install -g yo grunt-cli bower
終わり!

3.テンプレートをダウンロード

利用するテンプレートファイルをnpmでインストールします。
npm search yeoman-generator
ずらーと出てきます。まだ試してないですが、generator-backbonegenerator-angularとかもあって、だいたい30、40個ぐらいあるみたい.。。
とりあえず標準テンプレートのwebappをインストールします。
npm install -g generator-webapp

4.Webアプリ作成

mkdir testyeoman
cd testyeoman
yo webapp


     _-----_
    |       |
    |--(o)--|   .--------------------------.
   `---------´  |    Welcome to Yeoman,    |
    ( _´U`_ )   |   ladies and gentlemen!  |
    /___A___\   '__________________________'
     |  ~  |
   __'.___.'__
 ´   `  |° ´ Y `

Out of the box I include HTML5 Boilerplate, jQuery and Modernizr.
[?] Would you like to include Twitter Bootstrap for Sass? (Y/n) 
おっさん(Yeoman)きた!Twitter Bootstrap使いたいのでYes。
[?] Would you like to include RequireJS (for AMD support)? (Y/n) 
RequireJSもインストールしたいのでYes。
とすると色々ダウンロードが始まります。(結構時間掛かります。) 私はXcodeインストールしながらやったらPhantomJSのインストールで時間がすごく掛かりました。辛抱強く待ちましょう。。。 なお、インストール途中でキャンセルすると通信途中の壊れたZIPファイルが残って、以降再ダウンロードしてもエラーになりますので、その場合には上記ZIPファイルを削除してからやりましょう。
toshihiro308@Toshihirock-MacBook-Air:~/yeomantest$ ll
drwxr-xr-x  15 toshihiro308  staff    510  5 18 06:47 .
drwxr-xr-x+ 94 toshihiro308  staff   3196  5 17 22:31 ..
-rw-r--r--   1 toshihiro308  staff     44  5 17 22:31 .bowerrc
-rw-r--r--   1 toshihiro308  staff    415  5 17 22:31 .editorconfig
-rw-r--r--   1 toshihiro308  staff     11  5 17 22:31 .gitattributes
-rw-r--r--   1 toshihiro308  staff     56  5 17 22:31 .gitignore
-rw-r--r--   1 toshihiro308  staff    408  5 17 22:31 .jshintrc
drwxr-xr-x   4 toshihiro308  staff    136  5 18 00:15 .sass-cache
drwxr-xr-x   4 toshihiro308  staff    136  5 18 06:47 .tmp
-rw-r--r--   1 toshihiro308  staff  11002  5 17 22:31 Gruntfile.js
drwxr-xr-x  11 toshihiro308  staff    374  5 17 22:31 app
-rw-r--r--   1 toshihiro308  staff    208  5 17 22:31 bower.json
drwxr-xr-x  27 toshihiro308  staff    918  5 17 22:31 node_modules
-rw-r--r--   1 toshihiro308  staff    941  5 17 22:31 package.json
drwxr-xr-x   5 toshihiro308  staff    170  5 17 22:31 test
色々出来ています。 とりあえず起動っ!
grunt server
ブラウザが起動し、以下の画面が表示されます。

HTML5 Boilerplate,Twitter Bootstrap,RequireJSがインストールされてますよと!
bowerで確認するとこんな感じでした。
toshihiro308@Toshihirock-MacBook-Air:~/yeomantest$ bower list
bower discover Please wait while newer package versions are being discovered
yeomantest
├── jquery#1.9.1 (2.0.0 now available)
├── modernizr#2.6.2
├── requirejs#2.1.6
└─┬ sass-bootstrap#2.3.1
  └── jquery#1.9.1 (2.0.0 now available)
おお、超便利!。分かりやすい!

5.編集とか

先ほどのディレクトリのapp/index.htmlが表示されたページなので、これを編集したり、別途ファイルを作成したりして構築を行っていきます。

6.まとめ

上記の通り、ディレクトリ構成及びファイルが良い感じに配置されて、対応するようにGruntfileも作成されるのってのが良いですね。とりあえず、これでえいと環境つくってカスタマイズしていくと良さげ。

LiveReload機能がうまく動かなかったので別途調査予定。

2013年5月20日追記
LiveReload機能が動かないのはブラウザにLiveReload用のエクステンションをインストールしてなかったからでした。Chromeでエクステンションインストールしてやったらしっかり動きました。

2013年4月30日火曜日

Chrome Developer Toolsの変更履歴管理機能が便利だった話

このエントリーをはてなブックマークに追加 はてなブックマーク - Chrome Developer Toolsの変更履歴管理機能が便利だった話
ChromeブラウザのDeveloper ToolsにてCSSやJavaScriptのコードが編集出来たりしますが、その変更履歴を管理する機能があり、めちゃめちゃ便利なのでメモ。

SlideShareのChrome Developer Toolsを使いこなそう!を参考にさせて頂きました。

サンプル画面及びソースコード

以下の画面にて確認。
上記でCSSをいじってみたりした想定です。

変更してみる。

上記HTMLを表示し、Google Developer Toolsを表示します。表示は以下の通り。
  • 右上の設定アイコン→ツール→デベロッパーツール
  • ショートカット→(Windows:Ctl+Shift+i,Mac:Command + Option + i)
で、Sourceタブを表示します。
その後、左の矢印のアイコンをクリックし、今回はmystyle.cssを編集したいのでこれをクリックします。
とりあえずfont-sizeを50pxに変更し、保存(MacならCommand+s)します。
その後、右クリック→Local Modificationsを選択すると画面下に変更履歴が表示されます!!!
しかも。。
diffが見れます!!すげー!!!
その後、変更して、保存とするとここの履歴にどんどん追加されていきます。

変更を元に戻す場合

色々編集したけど最初の状態(オリジナルのファイルの状態)に戻したい、という時は変更履歴の箇所にあるrevertをクリックする事で元の状態になります。
なお、上記の方法だと今までの変更履歴も全て削除されます。変更履歴は残したいけど、内容を最初の状態に戻したい場合はapply original contentを選択する事で、変更履歴を残して元の状態に戻す事が出来ます。(正確には元の状態に戻す、という変更を行っています。なので、変更履歴の最終履歴として元のファイルへ戻した処理が追加されています。)

特定の変更を反映したい

変更を反映したい内容の箇所でapply revision contentを選択すると対応する変更箇所のみを現在の状態に反映する事が出来ます。

最後に

色々Google Developer Toolsは便利な機能が有りますが、この機能は特に便利だと思いました。今後の開発では是非有効活用していきたいです。

2013年4月29日月曜日

Chrome Developr Tools(Elementタブ)使い方メモ1

このエントリーをはてなブックマークに追加 はてなブックマーク - Chrome Developr Tools(Elementタブ)使い方メモ1
Code SchoolChrome Developer ToolsのElementタブの使い方の1コース目を終了したので、そのメモ。

Chrome Developer Tools起動方法

  • 右上の設定アイコン→ツール→デベロッパーツール
  • 右クリック→要素の検証
  • ショートカット→(Windows:Ctl+Shift+i,Mac:Command + Option + i)

Elementタブで出来る事。

  • HTML、CSSなどの編集が出来る。
  • 要素の編集、確認が出来る。
  • 要素の追加、移動、属性の変更なども出来る。

変更したいDOMの検索

  • 画面左のHTMLビューから探す。
  • 画面下の虫眼鏡アイコンを選択し、HTML画面の変更したいDOMをクリックする。
  • HTML画面の該当の要素の箇所で右クリックしてInspect Elementを選択する。

DOM操作

  • 画面左のHTMLビューで直接文字列などを変更可能。
  • 該当箇所で右クリックしてAdd Atributeで属性追加可能。
  • 該当箇所で右クリックしてDelete Nodeで要素を削除。
  • 該当箇所で右クリックしてEdit As HTMLで選択箇所のHTMLを編集可能。
  • ドラッグ&ドロップで表示位置の変更も可能。

編集ファイルの保存

  • 右クリック→copy as HTMLで編集したHTMLのコピーが可能。

dotcloudのWordpressからBloggerに移動しました

このエントリーをはてなブックマークに追加 はてなブックマーク - dotcloudのWordpressからBloggerに移動しました
dotcloud上にWordpressを立ててBlog的に使っていたのですが、dotcloudの無料プランが終了してしまいました。。。(今はアクセスも出来ない)

記事や記事で利用した画像ファイルは丁度先月ぐらいにdropboxAPIを利用して毎日バックアップするようにしていたので何とか全ての記事を復活させる事が出来ました。バックアップの詳細はこちら。[dropbox]dotcloudからdropboxAPIを利用してwordpressをバックアップしてみた[dotcloud]

どこかまた違うPaaSにWordpress立てても良いかと思いましたが、今回みたいな事がまた起きるような気もしたのでやめときました。

まあ、そんな感じでこちらでも時間を見つけて何か思いついたりしたら色々書いていこうと思います。

[JavaScript]JavaScript本格入門chapter5まで読んだメモ

このエントリーをはてなブックマークに追加 はてなブックマーク - [JavaScript]JavaScript本格入門chapter5まで読んだメモ

Bloggerへの移行前のWordpressにて2013-04-20に投稿した記事です。

JavaScript本格入門 ~モダンスタイルによる基礎からAjax・jQueryまで(amazon)のChapter5までを読んでメモっておこうと思ったコトをつらつらと。

オブジェクトリテラル(連想配列)のプロパティへのアクセス

var obj = {a:1, b:2, c:3};
alert(obj.a); // 1
alert(obj['a']); // 1

プロパティへのアクセス方法はドット演算子(.)もしくはブラケット構文の方法がある。

JavaScriptでは内部的に2進数で計算しているため、少数点を含む計算では誤差が発生

alert(0.2 * 3); // 0.600000.....1

これは0.6ではなく、0.600000000000…..1みたいになる。なので、if文とか使うときには注意が必要。

宣言した変数の確認

宣言した変数のデータ型を確認する際にはtypeof演算子を利用する。

var one = 1;
alert(typeof(one)); // number
var hello = 'hello';
alert(typeof(hello)); // string
var ary = [];
alert(typeof(ary)); // object

ただし、オブジェクト型の変数にtypeof演算子を利用すると全てobjectとなる。どのオブジェクトか判断するためにはinstanceof演算子を利用する。

var ary = [];
if(ary instanceof Array) {
    alert('ary is Array'); // aryがArrayの時に表示
}

try,cathc,finally構文もある

変数が未定義の場合、などのエラー検出が出来る。

try{
    alert(i);
} catch(e) {
    alert(e.message); // i is not definded
} finally {
    alert('finally'); // finally
}

上記例では、変数iが宣言されていないため、catch構文、finally構文が実行される。

Functionコンストラクタ経由で宣言する事で引数、関数本体を文字列として定義出来る。

関数の宣言をJavaScript組み込みのオブジェクトしてFunctionオブエジェクとが存在し、そのコンストラクタを利用して関数の定義が出来る。以下にコード例を示す。

var param = 'height, width';
var body = 'return height * width / 2;';
var function = new Function(param, body);

上記の記述法の利点として引数や関数本体を文字列で定義出来る。 上記により、例えば引数を変えたい場合、paramを変更し、関数の内容を変える場合にはbodyを変更すれば良い。

varを利用せず宣言された変数は全てグローバル変数扱い

ローカル変数のはずなのに何故かグローバル変数として参照されてしまっている場合には、この記述ミスを疑う。

関数で引数の数をチェックしない

function showName(name) {
    alert(name);
}

showName(); // undefined
showName('yamada'); // yamada
showName('yamada', 'kazuo'); // yamada

こんな感じで関数の引数と呼び出し元の引数の数が合わなくてもエラーとならない。関数の中でarguementsオブジェクトを使うと引数の数とかそれぞれの値が取得出来るので、柔軟な関数定義が出来る。

関数の引数,戻り値を関数で指定出来る。(高階関数)

タイトルの通り。 高階関数の引数として利用される関数がその場限りのみの利用の場合、匿名関数として利用するとコードがよりスマートとなる。

スコープチェーン

変数にどんな値が入っているか、というのは自分の階層から順番に上位の階層に向けて値が入っているかチェックしていくイメージ。

プロトタイプ

コンストラクタでメソッドを定義するとインスタンスの生成毎にメソッドを作成(メモリに確保)する。 上記より、メモリを多く利用してしまう。 この問題を解消する為に、メソッドを定義する場合にはprototypeプロパティを利用して宣言する方が余計なメモリを利用せずに良い。 以下にリテラル表現を利用してメソッドを定義した例を示す。

// class Car
var Car = function(name, company){
    this.name = name;
    this.company = company;
};

Car.prototype = {
    getInfo: function() {
        return 'Name = '+ this.name + ',Company = ' + this.company;
    }
};

var mycar1 = new Car('fit', 'honda');
alert(myCar1.getInfo());

静的メソッドの時、prototypeは利用出来ない。

タイトルの通り。宣言出来ない。 はまった。。。

[dropbox]dotcloudからdropboxAPIを利用してwordpressをバックアップしてみた[dotcloud]

このエントリーをはてなブックマークに追加 はてなブックマーク - [dropbox]dotcloudからdropboxAPIを利用してwordpressをバックアップしてみた[dotcloud]
Bloggerへの移行前のWordpressにて2013-03-31に投稿した記事です。

このBlogというかWordpressはdotcloudで動いているのですが、今までバックアップをとっておらず、それめっちゃ怖いと今更思い、定期的にバックアップをするようにしてみたのでその時のメモ。

概要

バックアップ対象としてはWordpressのDBwp-contentで、バックアップ先はdropboxになります。

バックアップ方法としてはDropboxAPIのPython版をdotcloudで動かせるようにしてcronで定期的にファイル送信するという感じです。

Dropboxへファイルを送信するする方法はdotcloudに特化している訳ではないので、それ以外のPasSや自分で管理しているサーバーでも出来るかも。

なお、dotcloudの場合、dbとWebサーバーが別インスタンスみたいなのでそれぞれに環境及びcronの設定を行いました。(一つの環境でできるやり方を知っている方いましたら教えて下さい。。。)

ちなみにプラグインがうまく動くようであれば、BackWPupとかが良い感じみたいです。(dotcloudだと上記プラグインうまく動きませんでした。。。。)

目次

  1. Dropbox Applicationの登録
  2. Python環境の準備
  3. DropboxAPIの設定、確認
  4. PUT用スクリプトの作成
  5. backup.shの作成
  6. cronの設定

1.Dropbox Applicationの登録

DropboxAPIを利用する為にアプリケーション登録を行います。
この情報は適当にググれば出てくるので省略します。

Access typeについはapp_folderにしました。(本エントリの確認も上記が前提です。)

下記サイトが参考になりました。
DROPBOX API(PYTHON)を使ってみる

2.Python環境の準備

Pythonが利用出来るようにvirtualenvを利用します。
dotcloudではPython自体は既にインストールされていましたが、モジュールをインストールする際に必要なsetuptoolsが無かったのでvirtualenvを利用しています。(virtualenvを利用するとsetuptoolsは一緒にインストール出来る)

dotcloudのwww,dbインスタンスの確認。
$dotcloud conncet <アプリケーション名>
$dotcloud info
=== wordpressapp
flavor:          sandbox
cost to date:    Free
+------+-------+------------+-----------------+
| name | type  | containers | reserved memory |
+------+-------+------------+-----------------+
| db   | mysql | 1          | N/A             |
| www  | php   | 1          | N/A             |
+------+-------+------------+-----------------+
wwwサーバーにログイン。
$dotcloud run www
DBサーバーにログイン。
$dotcloud run www
以降の処理は両サーバーで実行する。

ダウンロード、解凍
$wget https://pypi.python.org/packages/source/v/virtualenv/virtualenv-1.9.1.tar.gz
$tar -zxvf virtualenv-1.9.1.tar.gz
インストール、有効化
$cd virtualenv-1.9.1
$python virtualenv.py --distribute ENV
$source ENV/bin/activate

3.DropboxAPIの設定、確認

DropboxAPIのインストール及び、接続確認を行います。
基本的には公式のドキュメントDropbox Developerに書いてある通りに実行しました。

DropboxAPIのダウンロード、解凍
$wget https://www.dropbox.com/static/developers/dropbox-python-sdk-1.5.1.zip
$unzip dropbox-python-sdk-1.5.1.zip
DropboxAPIのインストール
$cd dropbox-python-sdk-1.5.1
$python setup.py install
Exampleコードを利用して接続確認を行います。
1.Dropbox Applicationの登録で登録したアプリケーションの情報でApp key,App secretが必要なので確認しておいて下さい。(webから確認できます。)

App key,App secretの編集
$cd example
$vi cli_client.py
cli_client.py
# XXX Fill in your consumer key and secret below
# You can find these at http://www.dropbox.com/developers/apps
APP_KEY = ''
APP_SECRET = ''
ACCESS_TYPE = 'app_folder'  # should be 'dropbox' or 'app_folder' as configured for your app
APP_KEY,APP_SECRETを入力して下さい。

また、Dropboxへのアプリ登録時にAccess typeをapp_folderじゃなく設定した場合にはACCESS_TYPEの変更が必要そうですがうまくいくかは未確認です。

適当にDropboxに送信するファイルを作成します。
$touch put.txt
サンプルコードの実行。
CLIでdropboxAPIが利用出来ます。
まずはログイン。
$python cli_client.py
Dropbox>login
url: https://www.dropbox.com/1/oauth/authorize?oauth_token=xxxxxxxxx
Please authorize in the browser. After you're done, press enter.
表示されたURLをブラウザで表示すると認証するかの確認画面になるのでAllowを選択。
その後、コンソールに戻ってenterを押します。
その後はDropboxAPIが使えます。(詳細はhelpを入力)

試しにファイルをputします。put後の名前はabc.txtとします。
Dropbox> ls
2013-03-31_04:00:01_UTC.data.tar.gz
2013-03-31_04:00:01_UTC.sql.gz

Dropbox> put put.txt abc.txt

Dropbox> ls
2013-03-31_04:00:01_UTC.data.tar.gz
2013-03-31_04:00:01_UTC.sql.gz
abc.txt
これでサーバーからファイルが送信出来る事が確認できました。

4.PUT用スクリプトの作成

下記参考にさせていただき、コードを少しだけ変えてシェルスクリプトから実行出来るようにします。
DROPBOX API(PYTHON)を使ってみる2
$cd dropbox-python-sdk-1.5.1/example/
$vi backup-wordpress.py
backup-wordpress.py
#!/usr/local/bin/python
# -*- coding: utf-8 -*-

import cmd
import locale
import os
import pprint
import shlex
import time

from dropbox import client, rest, session

# XXX Fill in your consumer key and secret below
# You can find these at http://www.dropbox.com/developers/apps
APP_KEY = ''
APP_SECRET = ''
ACCESS_TYPE = 'app_folder'  # should be 'dropbox' or 'app_folder' as configured for your app

def command(login_required=True):
    """a decorator for handling authentication and exceptions"""
    def decorate(f):
        def wrapper(self, *args):
            if login_required and not self.sess.is_linked():
                self.stdout.write("Please 'login' to execute this command\n")
                return

            try:
                return f(self, *args)
            except TypeError, e:
                #self.stdout.write(str(e) + '\n')
                print str(e)
            except rest.ErrorResponse, e:
                msg = e.user_error_msg or str(e)
                #self.stdout.write('Error: %s\n' % msg)
                print ('Error: %s' % msg)

        wrapper.__doc__ = f.__doc__
        return wrapper
    return decorate

class DropboxTerm():
    def __init__(self, app_key, app_secret):
        self.sess = StoredSession(app_key, app_secret, access_type=ACCESS_TYPE)
        self.api_client = client.DropboxClient(self.sess)
        self.current_path = ''

        self.sess.load_creds()

    def do_ls(self):
        """list files in current remote directory"""
        resp = self.api_client.metadata(self.current_path)

        if 'contents' in resp:
            for f in resp['contents']:
                name = os.path.basename(f['path'])
                encoding = locale.getdefaultlocale()[1]
                #self.stdout.write(('%s\n' % name).encode(encoding))
                print ('Filename=%s' % name).encode(encoding)
                #print ('FullFilename=%s' % f['path']).encode(encoding)

    @command()
    def do_cd(self, path):
        """change current working directory"""
        if path == "..":
            self.current_path = "/".join(self.current_path.split("/")[0:-1])
        else:
            self.current_path += "/" + path

    @command()
    def do_put(self, from_path, to_path):
        """
        Copy local file to Dropbox

        Examples:
        Dropbox> put ~/test.txt dropbox-copy-test.txt
        """
        from_file = open(os.path.expanduser(from_path), "rb")
        #from_file = open(from_path, "rb")

        self.api_client.put_file(self.current_path + "/" + to_path, from_file)

    @command()
    def do_rm(self, path):
        """delete a file or directory"""
        self.api_client.file_delete(self.current_path + "/" + path)

class StoredSession(session.DropboxSession):
    """a wrapper around DropboxSession that stores a token to a file on disk"""
    TOKEN_FILE = "token_store.txt"

    def load_creds(self):
        try:
            stored_creds = open(self.TOKEN_FILE).read()
            self.set_token(*stored_creds.split('|'))
            print "[loaded access token]"
        except IOError:
            pass # don't worry if it's not there

    def write_creds(self, token):
        f = open(self.TOKEN_FILE, 'w')
        f.write("|".join([token.key, token.secret]))
        f.close()

    def delete_creds(self):
        os.unlink(self.TOKEN_FILE)

    def link(self):
        request_token = self.obtain_request_token()
        url = self.build_authorize_url(request_token)
        print "url:", url
        print "Please authorize in the browser. After you're done, press enter."
        raw_input()

        self.obtain_access_token(request_token)
        self.write_creds(self.token)

    def unlink(self):
        self.delete_creds()
        session.DropboxSession.unlink(self)

def main(s):
    if APP_KEY == '' or APP_SECRET == '':
        exit("You need to set your APP_KEY and APP_SECRET!")
    term = DropboxTerm(APP_KEY, APP_SECRET)

    print(s);
    #term.do_rm(s[1])
    term.do_put(s[0],s[1])

if __name__ == '__main__':
    import sys
    args = sys.argv
    if len(args) > 1:
           s = args[1:]
    main(s)
引数を利用してファイルをputするようにしました。(といってもmain文をほんの少し変えただけですが。。。) ファイルをputする処理を実行する場合、以下のようにします。
$python backup-wordpress.py put.txt abc.txt

5.backup.shの作成

次に上記スクリプトを実行するシェルを作成します。
といってもdotcloudではバックアップ用のシェルスクリプトが用意されており、それを少しだけ変更すればOKです。

下記を参考にさせて頂きました。
DotCloudをDropboxへバックアップ 2

まずはdotcloudの公式サイトからバックアップ用のシェルをダウンロードしてきます。
$wget http://docs.dotcloud.com/_downloads/backup.sh
次に上記を変更します。
#!/bin/bash
# Syntax: 
# backup.sh <what> <how> <where> [whereexactly]
# <what> indicates what you want to backup: mysql, pgsql, riak, data.
# <how> indicates the backup method: ssh, ftp, s3.
# <where> is a <user[:password]@host>.
# [whereexactly] is an optional path on the <where> target, when applicable.
set -e
TAG="$HOSTNAME_$(TZ=UTC date +%Y-%m-%d_%H:%M:%S_UTC)"
source ~/virtualenv-1.9.1/ENV/bin/activate

: <<'#__COMMENT_OUT__'
[ "$3" ] || {
	echo "Please specify what to backup, how, and where."
	exit 1
}
#__COMMENT_OUT__


case "$1" in
	mysql)
		FILENAME="$TAG.sql.gz"
		FILEPATH="/tmp/$FILENAME"
		mysqldump --all-databases | gzip > "$FILEPATH"
		;;
	pgsql)
		FILENAME="$TAG.sql.gz"
		FILEPATH="/tmp/$FILENAME"
		pg_dumpall | gzip > "$FILEPATH"
		;;
	riak)
		FILENAME="$TAG.bitcask.tar.gz"
		FILEPATH="/tmp/$FILENAME"
		tar -czf "$FILEPATH" /var/lib/riak
		;;
	data)
		FILENAME="$TAG.data.tar.gz"
		FILEPATH="/tmp/$FILENAME"
		tar -C "$HOME" -czf "$FILEPATH" "data"
		;;
	*)
		echo "Sorry, I don't know how to backup $1."
		exit 1
		;;
esac

: <<'#__COMMENT_OUT__'
if [ "$4" ]
then
	DEST="$4/$FILENAME"
else
	DEST="$FILENAME"
fi
#__COMMENT_OUT__

case "$2" in
	ssh)
		scp -q -o BatchMode=yes "$FILEPATH" "$3:$DEST"
		;;
	ftp)
		curl -sST "$FILEPATH" "ftp://$3/$DEST"
		;;
	s3)
		s3cmd put "$FILEPATH" "s3://$3/$DEST"
		;;
	s3multi)
		split --numeric-suffixes --bytes=4G "$FILEPATH" "$FILEPATH".
		s3cmd put "$FILEPATH".?? "s3://$3/$DEST/"
		;;
	dropbox)
		cd ~/dropbox-python-sdk-1.5.1/example/
	        python backup-wordpress.py "$FILEPATH" "$FILENAME"
		;;
	*)
		echo "Sorry, transfer method $2 is not supported."
		exit 1
esac

SIZE="$(stat --printf %s "$FILEPATH")"
echo "Backup $TAG completed. Its (compressed) size is $SIZE bytes."
rm -f "$FILEPATH"
変更点は以下の通りです。
  • shをbashにした
  • source ~/virtualenv-1.9.1/ENV/bin/activateを利用してvirtualenvを使う。
  • 引数$3,$4は使わないのでコメントアウト(必須ではない)
  • 第2引数にdropboxと指定した場合、dropboxAPIを利用する用に設定
実行権限設定。
$chmod +x backup.sh
下記に利用方法について記載します。

1.MySQLのバックアップをdropboxへ送信する場合。
$./backup.sh mysql dropbox
2.wp-conentのバックアップをdropboxへ送信する場合。
$./backup.sh data dropbox

6.cronの設定

最後にcronの設定をします。といっても特別な事はしません。
必要に応じて時間は適当に変更して下さい。

DBインスタンス側。
$crontab -e
00 4 * * * ~/backup.sh mysql dropbox >> result.txt
wwwインスタンス側。
$crontab -e
00 4 * * * ~/backup.sh data dropbox >> result.txt

FuelPHP勉強会vol3に参加してきました

このエントリーをはてなブックマークに追加 はてなブックマーク - FuelPHP勉強会vol3に参加してきました
Bloggerへの移行前のWordpressにて2013-03-25に投稿した記事です。

FuelPHP勉強会vol3に参加してきました。

FuelPHPの勉強会への参加は初めてでした。
また、今回は思い切ってLTをしてみました。
以下のSlideshareがその時の資料になります。

 

発表は時間を結構オーバーしてしまったり、資料のページが長過ぎてかなり早口になってしまったのが反省点です。今後は気をつけよう。。。

メモは本当に個人用です。

メモ