私の歴史と今

振り返ると恥ずかしくなるのが私の歴史。だけどそのときは真面目に書いていた訳でね。そんな今の私を書いていく。

NetBeansを8.0.1にバージョンアップ

NetBeans7.4を使用していたが、Rubyの新しいHash形式に対応しておらず、赤い波線が邪魔になったのでバージョンアップした。(railsプラグインだけをバージョンアップすれば良かったのかもしれないが)

以下の通りやればいい。 NetBeans 8.0.1にRuby on Railsプラグインをインストールする手順 - Rails 雑感 - Ruby on Rails with OIAX

これでhoge:みたいなHash形式に波線が出ることがなくなった。

ただ、JavaのWebプロジェクトは旧バージョンのアプリケーションサーバがないって怒られる。まあそれは新しいのを指定すればいいだけなので、どうでもいい。

ちなみに、このバージョンアップで変更になったのは以下の点

  • nbproject/genfiles.properties
  • nbproject/private/private.xml
  • nbproject/private/private.properties
  • nbproject/build-impl.xml

以下、中身の差分。旧バージョンは削除していないので、新バージョンで動かなかったらファイルを戻すことにしよう。

diff --git a/nbproject/build-impl.xml b/nbproject/build-impl.xml
index de253be..d9dc47d 100644
--- a/nbproject/build-impl.xml
+++ b/nbproject/build-impl.xml
@@ -105,12 +105,24 @@
         <condition property="do.display.browser">
             <istrue value="${display.browser}"/>
         </condition>
+        <condition property="do.display.browser.debug.old">
+            <and>
+                <isset property="do.display.browser"/>
+                <not>
+                    <isset property="do.debug.client"/>
+                </not>
+                <not>
+                    <isset property="browser.context"/>
+                </not>
+            </and>
+        </condition>
         <condition property="do.display.browser.debug">
             <and>
                 <isset property="do.display.browser"/>
                 <not>
                     <isset property="do.debug.client"/>
                 </not>
+                <isset property="browser.context"/>
             </and>
         </condition>
         <available file="${conf.dir}/MANIFEST.MF" property="has.custom.manifest"/>
@@ -458,7 +470,7 @@ or ant -Dj2ee.platform.classpath=&lt;server_classpath&gt; (where no properties f
                     </fileset>
                 </union>
                 <taskdef classname="org.testng.TestNGAntTask" classpath="${run.test.classpath}" name="testng"/>
-                <testng classfilesetref="test.set" failureProperty="tests.failed" methods="${testng.methods.arg}" mode="${testng.mode}" outputdir="${build.test.results.dir}" suitename="nakayama_web" testname="TestNG tests" workingDir="${basedir}">
+                <testng classfilesetref="test.set" failureProperty="tests.failed" listeners="org.testng.reporters.VerboseReporter" methods="${testng.methods.arg}" mode="${testng.mode}" outputdir="${build.test.results.dir}" suitename="nakayama_web" testname="TestNG tests" workingDir="${basedir}">
                     <xmlfileset dir="${build.test.classes.dir}" includes="@{testincludes}"/>
                     <propertyset>
                         <propertyref prefix="test-sys-prop."/>
@@ -959,28 +971,28 @@ exists or setup the property manually. For example like this:
         <dirname file="${dist.war}" property="dist.jar.dir"/>
         <mkdir dir="${dist.jar.dir}"/>
         <jar compress="${jar.compress}" jarfile="${dist.war}">
-            <fileset dir="${build.web.dir}" excludes="WEB-INF/classes/.netbeans_*"/>
+            <fileset dir="${build.web.dir}" excludes="WEB-INF/classes/.netbeans_*,${dist.archive.excludes}"/>
         </jar>
     </target>
     <target depends="init,compile,compile-jsps,-pre-dist" if="do.war.package.with.custom.manifest" name="-do-dist-with-manifest">
         <dirname file="${dist.war}" property="dist.jar.dir"/>
         <mkdir dir="${dist.jar.dir}"/>
         <jar compress="${jar.compress}" jarfile="${dist.war}" manifest="${build.meta.inf.dir}/MANIFEST.MF">
-            <fileset dir="${build.web.dir}" excludes="WEB-INF/classes/.netbeans_*"/>
+            <fileset dir="${build.web.dir}" excludes="WEB-INF/classes/.netbeans_*,${dist.archive.excludes}"/>
         </jar>
     </target>
     <target depends="init,compile,compile-jsps,-pre-dist" if="do.tmp.war.package.without.custom.manifest" name="-do-tmp-dist-without-manifest">
         <dirname file="${dist.war}" property="dist.jar.dir"/>
         <mkdir dir="${dist.jar.dir}"/>
         <jar compress="${jar.compress}" jarfile="${dist.war}">
-            <fileset dir="${build.web.dir}" excludes="WEB-INF/classes/.netbeans_*"/>
+            <fileset dir="${build.web.dir}" excludes="WEB-INF/classes/.netbeans_*,${dist.archive.excludes}"/>
         </jar>
     </target>
     <target depends="init,compile,compile-jsps,-pre-dist" if="do.tmp.war.package.with.custom.manifest" name="-do-tmp-dist-with-manifest">
         <dirname file="${dist.war}" property="dist.jar.dir"/>
         <mkdir dir="${dist.jar.dir}"/>
         <jar compress="${jar.compress}" jarfile="${dist.war}" manifest="${build.meta.inf.dir}/MANIFEST.MF">
-            <fileset dir="${build.web.dir}" excludes="WEB-INF/classes/.netbeans_*"/>
+            <fileset dir="${build.web.dir}" excludes="WEB-INF/classes/.netbeans_*,${dist.archive.excludes}"/>
         </jar>
     </target>
     <target depends="init,compile,compile-jsps,-pre-dist,-do-dist-with-manifest,-do-dist-without-manifest" name="do-dist"/>
@@ -999,7 +1011,7 @@ exists or setup the property manually. For example like this:
         <dirname file="${dist.ear.war}" property="dist.jar.dir"/>
         <mkdir dir="${dist.jar.dir}"/>
         <jar compress="${jar.compress}" jarfile="${dist.ear.war}" manifest="${build.web.dir}/META-INF/MANIFEST.MF">
-            <fileset dir="${build.web.dir}" excludes="WEB-INF/classes/.netbeans_*"/>
+            <fileset dir="${build.web.dir}" excludes="WEB-INF/classes/.netbeans_*,${dist.archive.excludes}"/>
         </jar>
     </target>
     <target name="-post-dist">
@@ -1048,18 +1060,32 @@ exists or setup the property manually. For example like this:
     <target depends="init,-pre-dist,dist,-post-dist" name="verify">
         <nbverify file="${dist.war}"/>
     </target>
-    <target depends="run-deploy,-init-display-browser,-display-browser-nb,-display-browser-cl" name="run-display-browser"/>
+    <target depends="run-deploy,-init-display-browser,-display-browser-nb-old,-display-browser-nb,-display-browser-cl" name="run-display-browser"/>
     <target if="do.display.browser" name="-init-display-browser">
+        <condition property="do.display.browser.nb.old">
+            <and>
+                <isset property="netbeans.home"/>
+                <not>
+                    <isset property="browser.context"/>
+                </not>
+            </and>
+        </condition>
         <condition property="do.display.browser.nb">
-            <isset property="netbeans.home"/>
+            <and>
+                <isset property="netbeans.home"/>
+                <isset property="browser.context"/>
+            </and>
         </condition>
         <condition property="do.display.browser.cl">
             <isset property="deploy.ant.enabled"/>
         </condition>
     </target>
-    <target if="do.display.browser.nb" name="-display-browser-nb">
+    <target if="do.display.browser.nb.old" name="-display-browser-nb-old">
         <nbbrowse url="${client.url}"/>
     </target>
+    <target if="do.display.browser.nb" name="-display-browser-nb">
+        <nbbrowse context="${browser.context}" url="${client.url}" urlPath="${client.urlPart}"/>
+    </target>
     <target if="do.display.browser.cl" name="-get-browser" unless="browser">
         <condition property="browser" value="rundll32">
             <os family="windows"/>
@@ -1127,6 +1153,7 @@ exists or setup the property manually. For example like this:
         <nbstartserver debugmode="true"/>
         <antcall target="connect-debugger"/>
         <nbdeploy clientUrlPart="${client.urlPart}" debugmode="true" forceRedeploy="true"/>
+        <antcall target="debug-display-browser-old"/>
         <antcall target="debug-display-browser"/>
         <antcall target="connect-client-debugger"/>
     </target>
@@ -1143,9 +1170,12 @@ exists or setup the property manually. For example like this:
             </sourcepath>
         </nbjpdaconnect>
     </target>
-    <target if="do.display.browser.debug" name="debug-display-browser">
+    <target if="do.display.browser.debug.old" name="debug-display-browser-old">
         <nbbrowse url="${client.url}"/>
     </target>
+    <target if="do.display.browser.debug" name="debug-display-browser">
+        <nbbrowse context="${browser.context}" url="${client.url}" urlPath="${client.urlPart}"/>
+    </target>
     <target if="do.debug.client" name="connect-client-debugger">
         <webproject1:nbjsdebugstart webUrl="${client.url}"/>
     </target>
@@ -1240,6 +1270,7 @@ exists or setup the property manually. For example like this:
         <startprofiler/>
         <nbstartserver profilemode="true"/>
         <nbdeploy clientUrlPart="${client.urlPart}" forceRedeploy="true" profilemode="true"/>
+        <antcall target="debug-display-browser-old"/>
         <antcall target="debug-display-browser"/>
         <antcall target="-profile-start-loadgen"/>
     </target>
@@ -1330,7 +1361,7 @@ exists or setup the property manually. For example like this:
         <mkdir dir="${build.test.results.dir}"/>
     </target>
     <target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
-        <webproject2:test testincludes="**/*Test.java"/>
+        <webproject2:test includes="${includes}" testincludes="**/*Test.java"/>
     </target>
     <target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
         <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
diff --git a/nbproject/genfiles.properties b/nbproject/genfiles.properties
index c80c0ec..95028dd 100644
--- a/nbproject/genfiles.properties
+++ b/nbproject/genfiles.properties
@@ -4,5 +4,5 @@ build.xml.stylesheet.CRC32=651128d4@1.43.0.1
 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
 # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
 nbproject/build-impl.xml.data.CRC32=2f163b97
-nbproject/build-impl.xml.script.CRC32=eb5e2efb
-nbproject/build-impl.xml.stylesheet.CRC32=5459df51@1.43.0.1
+nbproject/build-impl.xml.script.CRC32=e59c0833
+nbproject/build-impl.xml.stylesheet.CRC32=99ea4b56@1.68.1.1
diff --git a/nbproject/private/private.properties b/nbproject/private/private.properties
index d68c6ea..7f1ec6e 100644
--- a/nbproject/private/private.properties
+++ b/nbproject/private/private.properties
@@ -5,4 +5,4 @@ j2ee.server.home=/Applications/NetBeans/apache-tomcat-7.0.34
 j2ee.server.instance=tomcat70:home=/Applications/NetBeans/apache-tomcat-7.0.34:base=apache-tomcat-7.0.34.0_base
 javac.debug=true
 javadoc.preview=true
-user.properties.file=/Users/junya/Library/Application Support/NetBeans/7.3/build.properties
+user.properties.file=/Users/junya/Library/Application Support/NetBeans/8.0.2/build.properties
diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml
index 4750962..6807a2b 100644
--- a/nbproject/private/private.xml
+++ b/nbproject/private/private.xml
@@ -1,4 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project-private xmlns="http://www.netbeans.org/ns/project-private/1">
     <editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/2" lastBookmarkId="0"/>
+    <open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2">
+        <group/>
+    </open-files>
 </project-private>

Firefox拡張機能をcfxを使って作る

次期バージョンのFirefox38からはNode.jsベースの新しい仕組みjpmが用意されるそうだけど、今まで古いxul形式の拡張機能を使ってきたので現行のpythonベースのcfxを使ってみた。

基本、以下のページの通りやっていけばいい。

developer.mozilla.org

cfxは以下の環境で使用可能だが、今回はMac Yosemite環境で使用してみた。

Python

cfxはPythonベースなので、Pythonが必要。ただし、Macには既にインストールされているので不要。

なお、Python2系でしか動作しないみたい。今回の環境は2.7.6だった。

$ python --version
Python 2.7.6

インストール

ここからダウンロードしてインストールする。 Installation - Mozilla | MDN

*でも、最終的にはHomebrewでインストールしました(後述)

$ mkdir ~/mozilla
$ cd ~/mozilla
$ tar -xf addon-sdk-1.17.tar.gz 
$ ln -s addon-sdk-1.17 addon-sdk
$ cd addon-sdk
$ ls -l
-rw-r--r--@   1 junya  staff   800  7 15  2014 LICENSE
-rw-r--r--@   1 junya  staff  1189  7 15  2014 README
drwxr-xr-x@   5 junya  staff   170  7 15  2014 app-extension
drwxr-xr-x@  10 junya  staff   340  7 15  2014 bin
drwxr-xr-x@   7 junya  staff   238  7 15  2014 examples
drwxr-xr-x@   8 junya  staff   272  7 15  2014 lib
-rw-r--r--@   1 junya  staff  2556  7 15  2014 mapping.json
-rw-r--r--@   1 junya  staff   269  7 15  2014 package.json
drwxr-xr-x@   7 junya  staff   238  7 15  2014 python-lib
drwxr-xr-x@ 155 junya  staff  5270  7 15  2014 test

シェルの確認

$ echo $SHELL
/bin/bash

開発する時は、毎回下記のアクティベート作業が必要らしい。

$ source bin/activate
Welcome to the Add-on SDK. For the docs, visit https://addons.mozilla.org/en-US/developers/docs/sdk/latest/

永続的に設定したい場合はPATHにcfxを通す。

ln -s ~/mozilla/addon-sdk/bin/cfx /usr/local/bin/cfx

と、ここまで来てわかったが、Homebrewでインストールすれば上記の作業などすべてが不要。。。ということで、削除してHomebrewでインストールした。

$ rm -f /usr/local/bin/cfx
$ rm -rf ~/mozilla
$ brew update
$ brew install mozilla-addon-sdk
==> Downloading http://ftp.mozilla.org/pub/mozilla.org/labs/jetpack/addon-sdk-1.17.zip
######################################################################## 100.0%
🍺  /usr/local/Cellar/mozilla-addon-sdk/1.17: 850 files, 5.7M, built in 2 seconds

$ which cfx
/usr/local/bin/cfx

cfxコマンドも通る

$ cfx
Usage: cfx [options] command [command-specific options]

Supported Commands:
  init       - create a sample addon in an empty directory
  test       - run tests
  run        - run program
  xpi        - generate an xpi

Internal Commands:
  testcfx    - test the cfx tool
  testex     - test all example code
  testpkgs   - test all installed packages
  testall    - test whole environment

Experimental and internal commands and options are not supported and may be
changed or removed in the future.

Options:
  --version             show program's version number and exit
  -h, --help            show this help message and exit
  -v, --verbose         enable lots of output

  Supported Command-Specific Options:
    -b BINARY, --binary=BINARY
                        path to app binary (run, test, testall, testex,
                        testpkgs)
    --binary-args=CMDARGS
                        additional arguments passed to the binary (run, test)
    --dependencies      include tests for all deps (test, testall, testex,
                        testpkgs)
    --extra-packages=EXTRA_PACKAGES
                        extra packages to include, comma-separated. Default is
                        'addon-sdk'. (run, test, testall, testcfx, testex,
                        testpkgs, xpi)
    -f FILENAME[:TESTNAME], --filter=FILENAME[:TESTNAME]
                        only run tests whose filenames match FILENAME and
                        optionally match TESTNAME, both regexps (test,
                        testaddons, testall, testex, testpkgs)
    -g CONFIG, --use-config=CONFIG
                        use named config from local.json (run, test, testall,
                        testex, testpkgs, xpi)
    -p PROFILEDIR, --profiledir=PROFILEDIR
                        profile directory to pass to app (run, test, testall,
                        testex, testpkgs)
    --package-path=PACKAGEPATH
                        extra directories for package search (run, test, xpi)
    --parseable         display test output in a parseable format (run, test,
                        testaddons, testall, testex, testpkgs)
    --pkgdir=PKGDIR     package dir containing package.json; default is
                        current directory (run, test, xpi)
    --static-args=STATIC_ARGS
                        extra harness options as JSON (run, xpi)
    --templatedir=TEMPLATEDIR
                        XULRunner app/ext. template (run, xpi)
    --times=ITERATIONS  number of times to run tests (test, testall, testex,
                        testpkgs)
    --update-link=UPDATE_LINK
                        generate update.rdf (xpi)
    --update-url=UPDATE_URL
                        update URL in install.rdf (xpi)

  Experimental Command-Specific Options:
    -a APP, --app=APP   app to run: firefox (default), fennec, fennec-on-
                        device, xulrunner or thunderbird (run, test, testall,
                        testex, testpkgs)
    --abort-on-missing-module
                        Abort if required module is missing (run, test,
                        testpkgs, xpi)
    --check-memory      attempts to detect leaked compartments after a test
                        run (test, testaddons, testall, testpkgs)
    --force-mobile      Force compatibility with Firefox Mobile (run, test,
                        testall, xpi)
    --force-use-bundled-sdk
                        When --strip-sdk isn't passed, force using sdk modules
                        shipped in the xpi instead of firefox ones (run, test,
                        testall, testex, testpkgs, xpi)
    --harness-option=KEY=VALUE
                        Extra properties added to harness-options.json (xpi)
    --manifest-overload=MANIFEST_OVERLOAD
                        JSON file to overload package.json properties (xpi)
    --mobile-app=MOBILE_APP_NAME
                        Name of your Android application to use. Possible
                        values: 'firefox', 'firefox_beta', 'fennec_aurora',
                        'fennec' (for nightly). (run, test, testall)
    --no-run            Instead of launching the application, just show the
                        command for doing so.  Use this to launch the
                        application in a debugger like gdb. (run, test)
    --no-strip-xpi      retain unused modules in XPI (xpi)
    -o, --overload-modules
                        Overload JS modules integrated into Firefox with the
                        one from your SDK repository (run, test, testall,
                        testex, testpkgs)
    --output-file=OUTPUT_FILE
                        Where to put the finished .xpi (xpi)
    --stop-on-error     Stop running tests after the first failure (test,
                        testex, testpkgs)
    --strip-sdk         Do not ship SDK modules in the xpi (run, test,
                        testall, testex, testpkgs, xpi)

  Internal Command-Specific Options:
    --addons=ADDONS     paths of addons to install, comma-separated (run,
                        test, testall, testex, testpkgs)
    --e10s              enable out-of-process Jetpacks (run, test, testex,
                        testpkgs)
    --keydir=KEYDIR     obsolete, ignored (run, test, testall, testex,
                        testpkgs, xpi)
    --logfile=LOGFILE   log console output to file (run, test, testex,
                        testpkgs)
    --profile-memory=PROFILEMEMORY
                        profile memory usage (default is false) (test,
                        testall, testex, testpkgs)
    --test-runner-pkg=TEST_RUNNER_PKG
                        name of package containing test runner program
                        (default is test-harness) (test, testall, testex,
                        testpkgs)

実際に使ってみる

このページに従って。 developer.mozilla.org

まず、init処理をして、空のアドオンを作成する。

$ mkdir -p ~/mozilla/test_addon
$ cd ~/mozilla/test_addon/

$ cfx init
* lib directory created
* data directory created
* test directory created
* generated jID automatically: jid1-EjwLVj320kcArw
* package.json written
* test/test-main.js written
* lib/main.js written

Your sample add-on is now ready.
Do "cfx test" to test it and "cfx run" to try it.  Have fun!

IDが勝手に振られ、各ディレクトリと、package.json、main.jsというファイルが作成される。

package.sonの中身は以下。main.jsは空。

$ cat package.json 
{
  "name": "test_addon",
  "title": "test_addon",
  "id": "jid1-EjwLVj320kcArw",
  "description": "a basic add-on",
  "author": "",
  "license": "MPL 2.0",
  "version": "0.1"
}

チュートリアルにあるように、main.jsを編集する。

$ cat lib/main.js 
var buttons = require('sdk/ui/button/action');
var tabs = require("sdk/tabs");

var button = buttons.ActionButton({
  id: "mozilla-link",
  label: "Visit Mozilla",
  icon: {
    "16": "./icon-16.png",
    "32": "./icon-32.png",
    "64": "./icon-64.png"
  },
  onClick: handleClick
});

function handleClick(state) {
  tabs.open("https://www.mozilla.org/");
}

拡張機能を動かす。

$ cfx run
Using binary at '/Applications/Firefox.app/Contents/MacOS/firefox-bin'.
Using profile at '/var/folders/93/2b32qdqn3v76tj1cnf6tmryc0000gn/T/tmperOXNA.mozrunner'.

Firefoxが起動して、右上にMozillaのアイコンが作成された。

f:id:mota5:20150420101605p:plain

ということで無事開発環境が整った。

拡張機能の自動更新

チュートリアルに乗っている通り、毎回cfx runを叩く手間を省くため、自動更新の方法も実施してみた。

そのコマンドの中でwgetを使っているのでMacにインストールする。(Macには標準でないのね・・・)

wgetをインストール rudix.org

次に自動更新用の拡張機能をインストール addons.mozilla.org

この拡張機能により、8888ポートで拡張機能更新用の待ち受けが行われるようだ。

これで準備ができたので、以下を実行して、5秒ごとに拡張機能をパッケージングし、アップロードする。

while true ; do cfx xpi ; wget --post-file=test_addon.xpi http://localhost:8888/ ; sleep 5 ; done

wgetでpost処理できることを知らなかった。。。

ちなみに、以下のような実行結果が出力されるが全く問題ない。

Exporting extension to test_addon.xpi.
--2015-04-19 22:49:18--  http://localhost:8888/
localhost (localhost) をDNSに問いあわせています... 127.0.0.1, fe80::1, ::1
localhost (localhost)|127.0.0.1|:8888 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 500 No Content
2015-04-19 22:49:18 エラー 500: No Content。

cfx to jpm

いまcfxで作っても捨てられる技術だから意味ないじゃん、とも思ったが、全部が無駄になるということでもないようなので、cfxで作ってしまっていいと思う。

developer.mozilla.org

In most respects, add-ons created with cfx will work fine with jpm. However, there are a few differences you have to know about.

railsのroutesで指定するshallowではまった

shallowではまったネタを。

shallowとは

railsにはRESTfulなURLを複雑にしないためのshallowというオプションが存在する。詳しくはこちらを。

railsguides.jp

実際の指定

実際にはこう指定している。

  namespace :admin do
    resources :accounts do
      resources :account_games, shallow: true
    end
  end

子リソースのidが決まっている場合はURLをネストする必要はないので大歓迎なのだが、_form.html.erbではまってしまった。

問題

form_forの引数でURLを決めるところで、newアクションを通そうとすると、editアクションでエラーになり、editアクションを通そうとするとnewでエラーとなる。。。なぜなら、newの時はURLに親リソースが含まれるが、editの時は親リソースが含まれないから。

rake routesでは以下のようになる。

   new_admin_account_account_game GET    /admin/accounts/:account_id/account_games/new(.:format)               admin/account_games#new
          edit_admin_account_game GET    /admin/account_games/:id/edit(.:format)                               admin/account_games#edit

解決方法

結局、ifで分岐する以外に方法がわからなかったので_form.html.erbは以下のようにした。

<%
if @account_game.id.nil?
  resource_info = [:admin, @account_game.account, @account_game]
else
  resource_info = [:admin, @account_game]
end
%>

<%= form_for(resource_info) do |f| %>

何かいい方法はないものか。