raspbery piをセットアップしたときにはまったこと(NOOBSを使う入れ方)
raspberry piを買ってみたのでセットアップしようと思ったけど色々はまった。
色々サイト見て回るとimgを手に入れてSDに書き込むとか大変そうなことが書いてある。
しかしダウンロードページに行くとNOOBS(New Out Of Box Software)というのが推奨されている。なんだこりゃ(はまった箇所その1)
悩みながら小一時間調べると最近はこのNOOBSというのをSDカードにぽんと放り込めば良いよということらしい。
そんなに簡単なんだ!
と思って入れても
dd: /dev/mmcblk0 Invalid argumet
というエラーが出てしまう (はまった箇所その2)。
改めてもう一度ちゃんと説明を読むとSDカードを「論理サイズ調整」(macなら「論理アドレス調整」)をONにしてフォーマットしなとダメだとか。
ということでここからダウンロード(左のメニューにダウンロードページへのリンクがあってとでもわかりづらい)したツールでフォーマット
できました!
教訓:面倒がらずに説明をちゃんと読みましょう。
ant初心者がivyでjarファイルの依存関係をなんとかしたい
npmの依存関係の解決とかを覚えてからJavaを触ってjarの依存関係って何とかならんのかねェ ってのを調べてみた。
すると出てきたやり方は3つ * maven * ivy (+ ant) * gradle
調べるとmavenはあまり良い評判が見られなかったので却下。
残るはgradleとivyでgradle。新規で始めるならこれでもよさそうだけど今回は既にantがあるのでivyを選んだ
公式のQuick startと結構まんまになってしまいそうだけどさらっとまとめる
ivy.xmlを書く
mavenリポジトリから探してこんな感じivy.xml
ファイルを書く。
ivy.xml
<ivy-module version="2.0"> <info organisation="myproject" module="mymodule"/> <dependencies> <dependency org="com.google.android" name="android" rev="4.1.1.4" conf="default->master"/> </dependencies> </ivy-module>
mavenリポジトリからコピーするとついてこないのだがconf="default->master"
という記述が無いとjavadocやsourceまで落とそうとする。後述のantで解決しようとした時に「Multiple artifacts of the module」みたいなエラーがでたらこれが原因。
ant タスクを追加
まず全体はこんな感じ
<?xml version="1.0" encoding="UTF-8" ?> <project basedir="." xmlns:ivy="antlib:org.apache.ivy.ant"> <property name="ivy.install.version" value="2.1.0-rc2" /> <property name="ivy.jar.dir" value="./lib" /> <property name="ivy.jar.file" value="${ivy.jar.dir}/ivy.jar" /> <path id="ivy.lib.path"> <fileset dir="${ivy.jar.dir}" includes="*.jar"/> </path> <target name="download-ivy" unless="offline"> <mkdir dir="${ivy.jar.dir}"/> <get src="http://repo2.maven.org/maven2/org/apache/ivy/ivy/${ivy.install.version}/ivy-${ivy.install.version}.jar" dest="${ivy.jar.file}" usetimestamp="true"/> </target> <target name="resolve" depends="download-ivy"> <taskdef resource="org/apache/ivy/ant/antlib.xml" uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/> <ivy:retrieve pattern="${ivy.jar.dir}/[artifact].[ext]"/> </target> </project>
公式サイトにのっているのを簡略化している。
基本的な部分
<project basedir="." xmlns:ivy="antlib:org.apache.ivy.ant">
にてivy用のxmlnsを追加。*1
ivy用の設定
<property name="ivy.install.version" value="2.1.0-rc2" /> <property name="ivy.jar.dir" value="./lib" /> <property name="ivy.jar.file" value="${ivy.jar.dir}/ivy.jar" /> <path id="ivy.lib.path"> <fileset dir="${ivy.jar.dir}" includes="*.jar"/> </path>
ivyを落としてくる場所を設定。このあたりは公式より簡略化している。
download-ivy タスク設定
<target name="download-ivy" unless="offline"> <mkdir dir="${ivy.jar.dir}"/> <get src="http://repo2.maven.org/maven2/org/apache/ivy/ivy/${ivy.install.version}/ivy-${ivy.install.version}.jar" dest="${ivy.jar.file}" usetimestamp="true"/> </target>
getなんてのを初めて知ったけどこれで落とせるようなので設定。
resolve タスク設定
<target name="resolve" depends="download-ivy"> <taskdef resource="org/apache/ivy/ant/antlib.xml" uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/> <ivy:retrieve pattern="${ivy.jar.dir}/[artifact].[ext]"/> </target>
先にivy.jarが必要なのでdepends=download-ivy
としている。
<ivy:retrieve pattern="${ivy.jar.dir}/[artifact].[ext]"/>
は結構色々やり方がある模様だけど未検証
実行
resolveタスクさえ実行すればよいので
$ant resolve
これで上記のxmlであればlibディレクトリにぐんぐんファイルが落とされてくれるので幸せです。
Intellijだとプラグインでやるようなやり方もありますが、Intellijは標準でant実行機能ついているのでそっちでそのまま走らせてしまうほうが最終的には楽な気がします *2
node.jsのprivateな関数のテストにrewireがすごく便利
node.jsでmodule.exportに書かない部分は外からアクセス出来ないプライベートな関数になる。 困っちゃうのがこれをテストしようとするとき。
結局テストのときだけ外に出したりutil作ったりといろいろ不恰好になって困っていたけど(rewire)rewireというモジュールがとても便利
例えばこんなモジュール
function initParams(input, options, callback){ if(typeof options === "function"){ callback = options; options = {}; } if(!options) options = {}; return { input : input, options : options, callback : callback } } module.exports = function(input, options, callback){ var params = initParams(input, options, callback) }
上記の場合、initParamsがprivateな関数になる。 ここでrewireさん登場。
var assert = require("assert") var rewire = require('rewire'); // ↓rewireでモジュールを呼び出す var myModule = rewire("../some_package.js"); // ↓__get__でprivateな関数を呼び出す var initParams = myModule.__get__("initParams") //あとは普通にassert var callback = function(){ }; var result = initParams("hoge", {"foo" :"bar"}, callback) var expect = { input : "hoge", options : {"foo" :"bar"}, callback : callback } assert.deepEqual(result, expect)
こんな感じで__get__
という関数でprivateな関数を呼び出せる。
__set__
というのもあって
myModule.__set__("fooValue", "1111"); myModule.__set__("barFunc", function(err, result){ assert.equal(expect, result) });
なんてこともできる
便利!
hubotのscriptを再帰的に読む & hubot-ircでnotice発言させる
はてなダイアリーのテストがてらhubotで詰まった部分&解決した部分
hubot scriptsディレクトリのスクリプトを階層化して読み込みたい
hubotのスクリプトは決め打ちになっている./scriptsか./src/scriptsから読まれる。
しかし一個のフォルダにぶっ込んだらわけわかんなくなってしまうのでさらっと書いてみた。
scriptの中で読ませるというやり方で解決。
__dirnameはnode.js的なこのスクリプトのあるフォルダを差し示している。
globというパッケージを利用しているので
npm install glob
をする必要アリ
hubot-ircでnotice発言させたい(荒業編)
hubotにirc発言をさせるhubot-ircだが、notice発言はデフォルトではできない。
結構色々な人が悩んでるみたいでforkしたり書き換えたりして解決していたが、書き換えたりするのが嫌だったのでちょっと荒っぽいやり方だけどこんな解決をしてみた。 hubot scriptとして読み込んでしまい、hubot-irc内のbot(実体はircというnodeのirc発言用モジュール)の発言(say)コマンドを上書き。
nickServer使っている部分でsayが呼ばれるのでnickServer使っている場合は使えなそう。
自分の環境ではそういう必要のあるircサーバーは無いのでどうなるかは未検証・・・
forkして書き換えた場合とくらべての利点としてはhubot-irc側に更新があっても基本的には追従できるってことぐらい
node-chromeを一日いじくり回してわかったこと
今朝方
http://www.moongift.jp/2013/02/20130216-2/
という記事を見つけた。
簡単にいえばnode.jsのUI部分をchromeに任せるようなものを作っちゃおう!って代物
過去にこういうことをやろうとしてchrome-extensionを作って挫折したりlocalhostの方をブクマしてたり色々やってた自分には朗報だったので早速node-chromeを触ってみた。
まずは普通にインストール
$mkdir node-chrome-sample $cd node-chrome-sample $npm init $npm install node-chrome
windowsだとインストール時にエラーが出る。ここについては後述するが、簡単に言うとエラー出ても問題なく動くっぽいのでこの場ではひとまず気にせず進める。
ソースを見てみる
https://github.com/hij1nx/node-chrome
メインとなるのはlib/index.jsだけでとても簡素。
肝になっているのは
var args = [ '--app=http://localhost:' + (opts.port || 8080) + opts.index, '--force-app-mode', '--app-window-size=' + (opts.width || 1024) + ',' + (opts.height || 760), '--enable-crxless-web-apps', '--user-data-dir=' + __dirname ];
このあたり。
なるほど。appモードとして起動するのか。その後のほうはサーバー起動をしてるみたい。
user-data-dirも別になっているのでchrome通常起動時とは独立した状態になっている。
デモを動かす
node-chrome/exampleにサンプルがあるのでとりあえずサンプルを起動
$cd node_modules/node-chrome/example $node demo
ん?動かん。
とソースを見ると
: var opts = { runtime: "/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome", :
あー・・・はい。すいません。macなんて高貴なもの持ってないんです。でも警告ぐらい出してくれても・・・
なので下記のように書き換え
: var opts = { runtime: process.env.LOCALAPPDATA+"\\Google\\Chrome\\Application\\chrome.exe", } :
再度起動。
動く。うむ。問題ない。
runtimeを決めてくれないのはなかなか痛い。パッケージで配布するときに困りそう。
とりあえず自分の何かをおいてみる。
demoが問題なかったのでちょっと簡易に作ってみる
index.js
var opts = { runtime: process.env.LOCALAPPDATA+"\\Google\\Chrome\\Application\\chrome.exe", files: "./view", port: port, index: "/index.html", }; var fs = require("fs") var client = require(".server.js"); cn(opts, function(websocket, chrome) { console.log("foo") chrome.on('exit', function (code) { process.exit(0); }); });
view/index.html
<html> <body> foo </body> </html>
で、起動
$node index.js
・・・・あれ?console.log(foo)としているのでコンソール上になにかしら出力がありそうなのに黙りこくられる。なんで・・・?
コードをもっかい見てみる
var wss = new WebSocketServer({ server: httpserver }); wss.on('connection', function(ws) { callback.call(this, ws, chrome); });
ハッ!callbackがwebsocketコネクション確立後に来ている!なんてこった!*1 *2
確かにdemoもwebsocketコネクションやっとる。
なのでwebsocketへの接続を追加。
<html> <script> var ws = new WebSocket("ws://localhost:8080"); </script> <body> foo </body> </html>
これで再度起動してみたら動く。うん。動いた・・・
言いたいことはあるけどまとめにて後述。
小ネタとか。
色々やってみて気づいたこともあるのでメモ。
ウィンドウサイズ
ウィンドウ画面のサイズが起動時に固定されているので
画面をサイズを変えて閉じる→再起動 とすると元の大きさに戻ってしまう
'--app-window-size=' + (opts.width || 1024) + ',' + (opts.height || 760),
という部分をコメントアウトしてやると保存されるようになるのでこれはぜひオプションが欲しいところ。*3
まとめ
- 最終的に起動されたときの感じはすげえいい。素敵。
- ただ結構不満がいろいろ・・・
- モジュールの方針としてchromeをうまいこと起動するだけにしてはruntime必須とかでちょっと気が効いておらず、サーバー周りについてはwebsocket部分に関してはws強制で自由度効かなくて辛い感じがあってちょっとそのまま使うのは辛い。
- どういうモジュールとして振りたいのか図りかねるので何かpull request投げづらい感強い。
- 個人的にはchrome起動のモジュールとして特化してくれたらありがたい。
- どういうモジュールとして振りたいのか図りかねるので何かpull request投げづらい感強い。
- runtimeの指定をうっかり間違うと無言で黙りこくられて捗らない。
- wsがwindowsでエラー出るしあんまり使いたくない。どうせローカルなんだしsocket.ioとかでも良いしなあ感。*4
- callbackイベントがwebsocketのconnection確立後に発動してるのでchromeの起動に成功したけどサーバー起動に失敗した時はchrome終了するとかも出来ないの辛い。
- モジュールの方針としてchromeをうまいこと起動するだけにしてはruntime必須とかでちょっと気が効いておらず、サーバー周りについてはwebsocket部分に関してはws強制で自由度効かなくて辛い感じがあってちょっとそのまま使うのは辛い。
- コード量も大したことないので今のところprocess.spawnして自前するという選択肢もありそう。
- 兎にも角にもchromeの起動部分は超有用なのでガンガン使って行きたい。
gitkのguiがwindowsで化けるとき
結構ググってみると
[gui] encoding = utf-8
というふうにするというのが多い。けど治らない。
[i18n] logOutputEncoding = utf-8
で治った!