2015年1月15日木曜日

Redmine 2.5 の markdown のテーブル内のセルに改行を入れる

どっちみち標準ではテーブルの中で改行が使えないのだが、
textileを使っている場合、昔から知られている対応がある。

単純に <br> タグが使えればいいのだが、
標準では有効なタグ以外はしまっちゃおうね〜、となっている。
で、その「有効なタグ」に <br> タグを追加する方法がこちら。

http://redmine.jp/faq/wiki/use-html-tag-in-wiki/

しかし、Redmine2.5から使用可能となったmarkdown(experimental)では、
この方法が使えない。
対応しても無視される。
どうやら、このファイルはtextileの場合のみ有効なようなのである。

experimentalだからって甘えてんじゃねえ!と憤ってみてもしょうが無いので、
どうにかする方法を考えてみるとする。

実はこのmarkdownのモジュール、
Redcarpetからの継承クラスとしてオリジナルレンダラを実装している。
それが以下のソースファイルである。

lib/redmine/wiki_formatting/markdown/formatter.rb

オリジナルレンダラの実装方法は、以下の記事に解説してある。

k0kubun's blog : Railsでカスタムmarkdownを実装する
http://k0kubun.hatenablog.com/entry/2013/09/19/223400

要は、オリジナルレンダラとして定義されている HTML クラスに、
ここに書いてある postprocess というメソッドを追加して、自力で対応すればいい。

しかし、HTMLタグ自体はここで処理されるまでにしまっちゃわれているので、
"[]"を使ってオリジナルタグ "[br]" を実装する方法で行ってみる。

と言うわけで、 HTML クラスに以下のメソッドを追加し、Redmineを再起動する。

def postprocess(full_document)
  full_document.gsub(/\[br\]/, '<br>')
end
単純に [br] って書かれてたら <br> に置換してるだけ。

あとは適当なところで [br] タグを試して見て下さい。改行されています。



2013年12月5日木曜日

OSX10.9 Mavericks に chef を入れる

有名な魔法の呪文でさくっと入れようと思ったが、

$ curl -L http://www.opscode.com/chef/install.sh | sudo bash   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current                                 Dload  Upload   Total   Spent    Left  Speed100  6789  100  6789    0     0  13186      0 --:--:-- --:--:-- --:--:-- 13208No builds for platform: 10.9Please file a bug report at http://tickets.opscode.comProject: ChefComponent: PackagesLabel: OmnibusVersion: Please detail your operating system type, version and any other relevant details

え、Mervirickは対応してないだと…。
うーん、gemで入れてもいいんだけどなんかもにょるので、ちょっとググってみた。

https://tickets.opscode.com/browse/CHEF-4678

すでにチケットに上がってるというかdupeしまくっとるなw
えーと、いくつかのworkaroundがチケットに上がってるね。
 Bakh Inamov added a comment - 14/Nov/13 6:57 PM
Downloaded https://opscode-omnibus-packages.s3.amazonaws.com/mac_os_x/10.7/x86_64/chef-11.8.0_1.mac_os_x.10.7.2.sh and ran w no issues
これを試してみたが特に問題なかった。なんか22Mくらいあるけどこのファイル。

つまり上記リンクからファイルをダウンロード。Macのターミナルでsudo使って実行すればすごい勢いでインストールされる。

2013年11月28日木曜日

GitLab6系でMerge Requestが作れない

実際に使ってるのはGitLab6.2.4ですが。

えーと、GitLabで普通にMerge Requestを作ってみようとしたんだけど、
Source Brancheとしてさっきコミットしたブランチが表示されない。
というか、リポジトリ作成してから始めて作ったブランチと、
masterおよびdevelopくらいしか表示されてない。

よく見ると、commitsのページでも存在してるはずのブランチが選択出来ない状態。
どうもドロップダウンに全く反映されていない様子。

なにこれ?と思ってググったところ、
https://github.com/gitlabhq/gitlabhq/issues/4864
これが見つかった。
この中のこの投稿
I checked on various projects and it seems that all of them a broken now, If I push a new branch to any of them, it is never displayed, not in the project home page (as a link to create a new MR), not in the branch dropdown in Commits tab and not in the MR branch dropdown (which I guess is probably the same a in the Commits tab).
It seems to be a cache issue because when I cleared the cache (cd /home/git/gitlab && sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production), the branch is now correctly shown in the dropdown menu.
I will make more test to check what goes on.
Where is the code for this dropdown, maybe I could tried to debug it on my setup?
ここに書いて有るとおり、railsのキャッシュをクリアするとちゃんと表示されるようになった。
え、まさかいちいちキャッシュクリアしないと反映されないとかじゃないよね…。
と思って続きを見ていって見る。

Clearing cache works because everything is generated on the first run thereafter, but any new commits afterwards will still not appear, because they are not processed. So my hunch would still be that the update hook doesn't work as intended.
Good idea would be to check all possible logs as well - maybe the hook does fire, but there is an internal error processing it.
ああうん。やっぱそうだよね。
キャッシュをクリアした後、一回全部作り直されるからちゃんと動いたように見えるが、
updateのフックがパーミッションの関係でちゃんと実行されてないので、
それ以降のブランチはやっぱり反映されないってか。

このトピックを読んでいくと、要点は以下の様な感じ。


  • キャッシュクリアすれば直る。
  • redisとgitlabを再起動しても直るし、しばらくは再現しなくなる。
  • しばらくすると再現するようになる。
  • 5.4でも同じようなバグがあり、とりあえずキャッシュクリアでなんとかしてた。
  • リポジトリのhooksからgitlab-shellへのリンクがおかしい場合も起こるが、これはリンクを正しくすれば直る。
  • gitlab-shellからredisへ接続する情報に関しても確認が必要。
  • 6.0時点でキャッシュクリアによって再現しなくなったが、6.1にupgradeしたら再現した。
  • 今の時点でもこのIssueは閉じられていない(完全には解決してない)


とりあえずのwork aroundとしては

  • キャッシュクリアする
  • gitlab関係を全部再起動する


で症状は治まるっぽい。
しばらく様子を見て、最悪cronでキャッシュクリアを回すしか無いか…。

2013年10月29日火曜日

arch already exists in fat dylib

タイトルのエラーが突然出てきた。
CleanしてもBuildしても出てくる。なんだこれは。
とりあえずググるといつもの通りのStack over flowの記事がヒット。

http://stackoverflow.com/questions/18392902/arch-already-exists-in-fat-dylib-in-build-log

以下意訳。
「いきなり "arch already exists in fat dylib" とかすごい勢いでビルドログに出力されて困ってるんですけどどうしたらいいですか?」
「ろくな情報もねえのに分かるかよ。こんなもんオフトピだ」

で即クローズされてる。もうちょっと優しくしてあげてよ…。

自分はAppCode使ってるので、ちょっとXcodeでビルドしてみるかーと思ってやってみたら、バックグラウンド処理を動かそうと思って書いた以下のコードで "Initializer element is not a compile-time constant" というエラーが。
static UIBackgroundTaskIdentifier bgTask = UIBackgroundTaskInvalid;
この "UIBackgroundTaskInvalid" だけど、定義はこうなっている。
typedef NSUInteger UIBackgroundTaskIdentifier;
UIKIT_EXTERN const UIBackgroundTaskIdentifier UIBackgroundTaskInvalid  NS_AVAILABLE_IOS(4_0);
つまり、バージョンが決まらないと定義が決まらないので、この定数っぽいシンボルは実は実行時でないと実際に参照出来ないわけだ。エラー内容もそういう内容。

というわけでこれを直してAppCodeでビルドしてみると、タイトルのエラーも無くなり一件落着。

これはあれか、コード解析処理でなんか変な事になってるって事なのかな…。
最初に出したSOFのURLの人も、jenkinsでビルドしてて出たって言ってるので、サードパーティ環境でのみ出るのかもしれない。

日本語の記事が一つも引っかからなかったのでここに記す。
これ気付かないとドはまりする案件だと思うので皆さん気を付けて下さい。

2013年2月4日月曜日

Package file was not signed correctly

掲題は「パッケージファイルに正しく署名されていません。」の英語版。

前回のエントリーで書いた内容では解決されない場合、パッケージ側に問題がある。
何をやっても現象の再現する機種が存在する訳だ。
で、まず確認すべきは

「再現する実機のLogcatを取る」

である。インストール時に「PackageParser」というタグでエラーが出ているはず。
出てない場合はご愁傷様という他ないが…。
あと再現する実機を入手するのが以外と大変かもしれない。

大抵はこのエラーの原因となるファイルを取り除くことで解決する。
以下のGoogleGroupの投稿では、xmlファイルがなんかおかしくなったと有る。

http://productforums.google.com/forum/#!category-topic/android-market/technical-help/JzAgJ414CQc

なんでこんな事が起こるかというのはさっぱり不明の様だが、掲題のフレーズで検索すれば、英語圏では山ほど同様の現象は起きているらしい。

他にはこちらの投稿。

https://groups.google.com/forum/?fromgroups=#!topic/android-developers/gAUqJkCuAvE

証明書の期限は大丈夫か?という内容。

大体このあたりに原因があるらしい。

2013年2月1日金曜日

パッケージファイルに正しく署名されていません

今回の記事はただのメモ。
 
要点だけ先に書くと、「アンインストールしてインストールし直す」だけです。
あなたがユーザーならまずこれを試してからクレームを入れるようにしてください。
これでダメなら、リリースモジュールに問題が有ると思っていいでしょう。
その場合、開発者の方は本記事の最後を見て下さい。
ユーザーの方は出来ればTwitterとかメールで直接教えてあげると感謝されますよきっと。

まず前提。
Androidアプリのリリースをするためには署名を行わなければならない。
これは、GooglePlayアップロードしたアプリを勝手に差し替えられないためである。

この仕組みのため、最初にアプリをアップロードする時に使った署名用の鍵を無くすと、そのアプリは更新が出来なくなる。

・・・という仕組みがAndroidでは利用されている。たぶんiPhoneも大体同じだが。

で、困ったことに、ダウンロード済みアプリの署名がおかしくなる場合があるらしい。
この時、アプリの更新をGooglePlayから行おうとすると、掲題のエラーではじかれてしまう。

これに関しての参考URLがこちら。

モノクロメカニズム: GALAXY NoteにカスタムROM≪ROCKET ROM v22≫を焼いてみた

こちらにはプリインストールアプリが上記現象でアップデート出来ないことが言及してある。

Logging Quest

自動探索RPG(放置型RPG)らしい。アプリの説明に、
【更新時に「正しく署名されていないパッケージファイルです」エラーが出る場合】
原因を調査しましたが、アプリ、端末を問わず、稀に発生する現象のようです。以下をお試しください。
*
ホームからメニューを開き、アプリケーション、アプリケーションの管理、と選択(機種により若干異なります)。「マーケット」を選択して「データを消去」「キャッシュを消去」を行う。

* 端末をシャットダウンし、再起動してみる。
* SDカードを取り外して更新してみる。
改善されない場合は、アプリ側では残念ながら対策不能のようです。
アンインストールし、再インストールすれば、更新できるようですが、既存のセーブデータは消えてしまいます。
申し訳ありませんが、よろしくお願いいたします。
 と書かれている。苦労されたのだろう。心中お察しします。

お部屋でモバイル: Androidでプリインストールの更新がうまくいかないとき

こちらもプリインストールアプリでこの現象が起こったときの対処法です。


2012年8月21日火曜日

ProGuardによるライブラリとしてのJARの難読化(2)

というわけで昨日の続き。
実際にProGuard4.8を使ってライブラリJARを難読化してみます。


 これはProGuardの起動直後の画面。
左側に各設定項目が並んでいます。
右下の「Next」を押すと、各設定項目間を進んでいきます。正直いらん。




 「Input/Output」の設定画面。
ここではInputとして難読化対象のJARなどを指定し、
どこにOutputするかを設定します。
また、前提となるライブラリとかもココで指定します。

ココで重要なのは
  • 実際に使用しているAndroidのバージョンに応じたandroid.jarをライブラリとして指定する
ことです。デフォルトではjavaの共通ライブラリが指定されているのですが、それは消しましょう。
android.jarに含まれています。
android.jarはAndroidSDKの「platforms」の中にあるよ。
他にも自作JARで使用しているライブラリがあるならココで指定しておけば取り込まれます。

一応注意だけど、「Input」として指定するのと、「ライブラリ」として指定するのは意味が違います。
「Input」したクラスは全て処理されて「Output」に吐き出されます。
「ライブラリ」として指定したクラスは解析に利用されるだけで処理対象にはなりません。


とりあえずこれだけ設定すれば、処理を行う事は出来るのですが、
デフォルトのままだと全部Shrinkされて何も無いJARが出力されてしまうので、
いくつか設定が実際必要。


 というわけでShrinkingの設定画面です。
Shrinkingとは、不要なクラスを削除してライブラリを小さくしてくれる処理なのですが、
今回のようにライブラリ「だけ」でShrinkすると、実際に使ってるクラスひとつもねーじゃん!となり、
全部のクラスが排除されます。慈悲は無い。
(本来はアプリケーションのエントリポイントからクラスの参照ツリーが形成されて、残すクラスが決定される)

というわけで、「Keep」の設定が必要になるわけです。
この画面の上側の設定項目は標準状態のままで問題ないので、
下の方にある「Keep additional classes and class members」を設定します。

ここでは二つ指定しています。
消しについては気にしないで下さい。
それぞれ
「Class example.android.library.**」「Class example.android.util.io.**」と書いてあることにします。
書式については該当のエディットボックスにカーソル持って行くとバルーンヘルプが出るのでそれを読んで下さい。

要は、ここで指定したクラスはShrink対象から除外されて、キープされる訳です。
なので、ライブラリの公開クラスを指定しておけばうまいことしてくれるようになります。

クラス指定は単純な名前指定だけでは無く、見ての通りのワイルドカード指定と、
さらにクラスの属性によるフィルタリングなどにも対応しています。
たとえば、名前自体はワイルドカードで広く指定して、その中でも「public」のクラスだけをkeepする等。
まぁ細かいことはどうでも良い場合は名前だけで良いです。



次にObfuscationの設定です。
基本的にはShrinkと同様、難読化したくないクラスをここでKeep設定しておきます。
普通はShrinkと同じ設定になるんじゃないでしょうか。
加えて、ライブラリ内で定義したクラスを公開メソッドの引数に使ってたりする場合は、それもKeepしないと外から分からなくなるので設定します。
上記画面ではちょうどそんな感じのことをしています。

注意点をまとめておくと
  • 外部で使うクラスはShrink/Obfuscation共にKeep
  • Keepしてるクラスのメソッドの引数、返値の型のクラスもKeep (ShrinkはされないのでObfuscationだけ)
  • AIDLがらみのクラスもKeepしておく。
  • 外部で使うクラスはinner classとして宣言しない。難読化まわりでハマるので。listenerとかでもtop levelクラスとして独立で定義しておく。
最後の項目で大ハマリしたのがこの記事を書くきっかけな訳だが。
実際の所、inner classは例えば「example.android.library.hoge$huga」の様に、
親クラス名に「$」付けてインナークラス名を付ければProGuardとしては参照出来るんだけど、
JARをインポートしたアプリ側からの参照がうまく出来ない。
難読化対象からは確実に外れているにもかかわらず、だ。
この辺はソース参照とclassファイル参照の違いだと思うんだけど、面倒なので独立定義にした方が良いです。
どうせアプリに公開しなきゃいけないインターフェースなので、明示的にした方がいいでしょうし。

なお、調査のためには「Print mapping」を有効にすると、どう難読化されたかを吐き出してくれます。

あとは「Optimization」とかあるけど、これは標準で良いんじゃ無いかな。
マニュアルの方にはループが過剰最適化される場合とか載ってるので、問題が有る場合とかに外した方が良いことがあるかも?

 一通りできたら「Process」ページの右下に「Process!」ってボタンがあるので、押せば設定通りに処理してくれます。
このときにエラーがあったら教えてくれるので、もしもなんか出てきたらよく読んで対処。
ちょくちょくあるのはKeep設定したクラスで記述されてるクラスがKeepされてないよ?というNoteかな。
言われたクラスもKeepしないと、ただしくKeepされません。


あとは実際にアプリの方でインポートして動作確認できれば完了。