GitLabを使ったプライベートGitリポジトリーの管理を止め改造版 Ginatra にしました。

プライベートGitリポジトリーの管理

私の会社 EY-Ofiice零細企業なので プライベートGitリポジトリーGitHub等の有料サービスではなく、さくらクラウド上のサーバーで GitLab を動かしてきました。 しかし、

  • 通常の開発は一人でしか行わないのでpull request等の機能はいらない
  • GitLabは処理が重くサーバーのメモリーを増やさないと遅すぎる
  • 複数人で開発するような仕事ではお客様側でGitHub等を用意してくれる
  • 教育でGitLabを使う事があるが、その時だけGitLab用サーバーを用意すれば良い気がする

ということで、あまりメリットを感じていませんでした。

Gitを使い始めた頃は GitWeb でリポジトリーや履歴が表示と。自作した新規リポジトリー作成CGIで運用していました。

Ginatra

Git用のWebツール を見ていたらSinatraベースの Ginatra ( GitHub ) を知り、インストールしてみました。

Ginatraは Gitリポジトリーのファイル(コード)や履歴の表示ツールです。Sinatraベースなので動作も軽いし、メンテも楽で、今風の画面デザインも気に入りました。

Ginatraの改造

ただし、不満もあり Fork し機能を追加。変更しました。

1. リポジトリーの階層化

Ginatraは複数のGitリポジトリーディレクトリーをサポートしていますが、フラットに管理しています。EY-Officeでは docs(ドキュメント), edu(教育用), products(製品)・・・などのディレクトリーの下にGitリポジトリーを置いています。GitLabには Groupという機能がありこれを使っていました。

やはり、グループが無いと不便なので Repo クラスに group属性を追加し group:nameレポジトリーの識別子として使うように改造しました。 また、一覧表示は Bootstrap の Collapse(Accordion) を使い表示するようにしました。

f:id:yuum3:20150811153016p:plain

2. 新規リポジトリーの作成

Web上かから新規にGitリポジトリーが作成作成出来るようにしました。Ginatraで使っているRugged (libgit2のRubyインターフェース)に git init のAPIがあったので簡単にできました。

f:id:yuum3:20150811153029p:plain

3. その他

などです。まだ RSpec を修正していません ^^;

RedmineのコンテンツをMarkdownに変換しました

Textile vs Markdown

軽量マークアップ言語にはたくさんの種類があります。私も教育で使うテキストの作成やRedmineWikiでは長年 Textile を使って来ました。 しかし、最近はGithubの標準のマークアップ言語がMarkdownだったり、Atom(エディター)をはじめたくさんのMarkdownをサポートするツールが現れ、私も MacDownというツールが気に入り開発ドキュメント等のMarkdown化がどんんどん進んでいます。このブログもはてな記法ではなくMarkdownを使っています。

TextileとMarkdownを比べると 標準のMarkdown は記述能力が低くテキストを作るには能力不足ですが、 GitHubの拡張php Markdown Extra などの拡張機能を使えば、ほぼ同等です。

Redmine

Redmineマークアップ言語のデフォルトはTextileですが、Version 2.5からMarkdownをサポートするようになりました。ただし、Redmineサーバー全体の設定なので新規にRedmineを始める人以外には使いにくいものでした。 redmine_persist_wfmtのようなプラグインを使えばコンテンツ(Wiki, Ticket...)単位でTextitle/Markdownが選択できるのでこれを使えば良いかもしれません。

しかし、私はRedmineWikiを教育でよく使っています。お客様毎に教育で使うコード、ヒント、参考情報・・・などをWikiを使い提供しています。しかも以前に作ったWikiを元に作成する事が多いので、そのTextileとMarkdwonが混在するのは望ましくありません。

そこで、Textileコンテンツを全てMarkdownに変換してしま事にしました。

Textile to Markdown

"Convert Textile to Markdown" で検索すると Pandoc というドキュメント変換ツールが良く出来てきます。このツールは色々なドキュメント形式を相互変換できる素晴らしいツールですが、やはり完璧ではありませんでした。 Markdown→TextileではGitHub拡張をサポートしていますが、Textile→MarkdownではテーブルをGitHub拡張に変換してくれたりしません・・・

そこで、自作を検討しました。MarkdownとTexitleは似ています、正規表現を使えばほとんど変換できます。

def textile_to_markdown(textile)
  d = []
  pre = false
  table_header = false
  text_line = false

  textile.each_line do |s|
     s.chomp!

    if pre
      if s =~ /<\/pre>/
        d << "~~~"
        pre = false
      else
        d << s
      end
      next
    end

    s.gsub!(/(^|\s)\*([^\s\*].*?)\*(\s|$)/, " **\\2** ")
    s.gsub!(/(^|\s)@([^\s].*?)@(\s|$)/, " `\\2` ")
    s.gsub!(/(^|\s)-([^\s].*?)-(\s|$)/, " ~~\\2~~ ")
    s.gsub!(/"(.*?)":(.*?)\.html/, " [\\1](\\2.html) ")

    d << ""  if text_line
    text_line = false

    case s
    when /^<pre>/
      d << "~~~"
      pre = true
    when /^\*\*\* (.*)$/
      d << "      * " + $1
    when /^\*\* (.*)$/
      d << "   * " + $1
    when /^\* (.*)$/
      d << "* " + $1
    when /^\#\#\# (.*)$/
      d << "      1. " + $1
    when /^\#\# (.*)$/
      d << "   1. " + $1
    when /^\# (.*)$/
      d << "1. " + $1
    when /^h(\d)\. (.*)$/
      d << "#" * $1.to_i + " " + $2
    when /^!(.*?)!/
      d << "![](#{$1})"
    when /^\|_\./
      d << s.gsub("|_.", "| ")
      table_header = true
    when /^\|/
      d << s.gsub(/\=\..+?\|/, ":---:|").gsub(/\s+.+?\s+\|/, "---|") if table_header
      table_header = false
      d << s.gsub("|=.", "| ")
    when /^\s*$/
      d << s
    else
      d << s
      text_line = true
    end
  end

  d.join("\n") + "\n"
end

このコードは全てのTextileフォーマットをサポートしているわけではありませんが、私が使ってる機能はほぼ網羅しています。 変換されたMarkdownはGitHub拡張やphp Markdown Extraの機能を使っています。

さてRedmineでは色々なところにTextileが書けますが、今回は Wiki, Ticket, Ticketの履歴のコンテンツに対応しました。必要があれば追加して下さい。

def update_content(model, attrbute)
  total = model.count
  step = total / 10
  puts "  #{model}.#{attrbute} : #{total}"
  model.all.each_with_index do |rec, ix|
    n = ix + 1
    puts sprintf("%8d", n)   if n % step == 0
    rec[attrbute] = textile_to_markdown(rec[attrbute])  if rec[attrbute]
    rec.save!
  end
end

update_content(WikiContent, :text)
update_content(Issue, :description)
update_content(Journal, :notes)

コードは Gistにも置きました。

このコードを以下のように runnder で実行するとTextileがMarkdownに変換されます。

$  rails runner -e production tools/textile2md.rb  

注意: このプログラムは全てのTextile形式を変換できるものではありません、またバグ等で正しく変換できない場合もありますので、変換前に必ずRDBのバックアップを取って下さい。

iOS 開発者のためのバックエンド入門 (2)

iOS開発者の勉強会 yidev 第20回勉強会iOS 開発者のためのバックエンド入門 (2) という発表をしました。 iOSだけでなく、Androidの開発者の方にも参考になる話だと思います。

今回の内容は、Ruby on Railsを使い簡単なバックエンドをその場で作ってみるという実演付きの話をしました

Ruby, Ruby on Railsに付いて

Ruby on Rails を使い簡単なバックエンドを作る

  • クライアントになるiOS アプリの紹介 ーー Swiftで作りました
  • Ruby on RailsのScaffoldでバックエンドを作る実演

f:id:yuum3:20150712112536p:plain

バックエンドをHerokuにデプロイ

  • 出来たバックエンドを代表的なPaaS (Platform as a Service) である、Heroku にデプロイする
    • ライブラリー構成を少し変え、Herokuにgit pushするだけでデプロイが完了
    • Herokuへのデプロイ手順はHerokuのページにもありますが、RailsGirlのHeroku の Rails アプリをアップページ が判りやすいです

コード、資料

使ったコードは GitHub におきました

iOS 開発者のためのバックエンド入門 (1)

iOS開発者の勉強会 yidev 第18回勉強会iOS 開発者のためのバックエンド入門 (1) という発表をしました。 iOSだけでなく、Androidの開発者の方にも参考になる話だと思います。

今回の発表で伝えたかった事は

バックエンドを作るにはいろいろな選択肢がある

  • Parse.comに代表される BaaS (Backend as a Service)を使うとプログラミングやサーバーの構築なしにバックエンドが持てます。ただしBaaS側が提供している機能(データ共有、プッシュ通知...)出来ることには限界があります。
  • BaaSの中には StrongLoopのように、プログラミング出来る自由度の高いものもあります。
  • たいていのBaaSは、お試し的な利用は無料ですが負荷が高くなると課金されます。ビジネスの場合にはコスト的にも独自のバックエンドを作るという選択もあります。
  • 独自のバックエンドを作る場合には、プログラミング言語フレームワーク... とたくさんの選択肢があります。これはどの用途でもベストという解答はないので、目的に応じて選んで下さい。

独自のバックエンドを作る場合、最初はPaaSがお勧め

インフラは知識だけでなく、安定したインフラを運用して行くには経験も必要になります。

しかし、Heroku に代表される PaaS (Platform as a Service) を使うとインフラの知識(エンジニア) 無しに始められのでお勧めです。

APIフレームワークGrapeをRuby on Railsの中で動かすと遅いぞ

ある仕事でスマフォ用のAPIサーバーを作る事になり、REST-like APIが簡単に作れるフレームワーク grape を調査してみました。grapeの良さは、DSLで簡単にAPIサーバーが書ける点とRackで動く軽いフレームワークなのでRuby on Railsに比べ高いパフォーマンスが期待できる点です。

システム構成

Grapeは Mounting に書かれているようにいくつかの構成で動かせます

今回のシステムでは管理者用のWebアプリは Ruby on Railsで作るので、モデルを共有できるRuby on Railsに組み込み使うのが魅力的です。

評価用コードを作ってみた

準備

  • まずはRailsのプロジェクトを作り、scaffoldでいつものアプリを作成
$ rails new api_test
$ cd apt_test
$ rails g scaffold todo due:date task:string
  • テストデータ作成 db/seed.rb も作成
Todo.delete_all
100.times { |i| Todo.create!(due: Time.now + i.day, task: sprintf("task%02d", i)) }
  • 性能比較のために app/views/todos/index.json.jbuilder を変更
json.array!(@todos) do |todo|
  json.extract! todo, :id, :due, :task, :created_at, :updated_at
end

Grape

grape ページの情報を基に API を作成

  • Gemfile
source 'https://rubygems.org'
  ....
gem 'grape'
  • API のコード
class SimpleApi < Grape::API
  version 'v1'
  format :json

  resource :todos do
    desc "Return all todos."
    get  do
      Todo.all
    end
  end
end
  • config/routes.rb に APIをマウント
Rails.application.routes.draw do
  resources :todos
  mount SimpleApi => '/api'
end
  • config/application.rb にAPIのコードを読み込むように設定
module ApiTest
  class Application < Rails::Application
    ....
    config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb')
    config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')]
  end
end

これで http://localhost:3000/api/v1/todos をアクセスするとtodosテーブルの全内容がJSONで取得できます

性能が気になる

Ruby on Railsのコードも http://localhost:3000/todos.jsonJSONを返せるます。grapeがどれくらい性能が良いのかを比較してみました。

比較する環境は実際の環境に近くなるように

  • RAILS_ENV は production
  • サーバーは unicorn、worker_processes は 4
  • アプリは EC2 t2.micro で実行
  • ただし、RDBはsqlite3のまま、Nginx等のフロントエンドは無し

ab -c 8 -n 1000 URL で性能を計測

Framework Requests per second
Grape within Rails 33.66
Ruby on Rails 34.49

Grape の性能は Ruby on Rails と同じくらい!? もちろん、テストデータ、abのパラメータにより多少状況は変わりますが・・・

ActiveRecord without Railsを試した

Rackの上で直接動くシンプルな grape の性能がこんなに低いのは納得出来なかったので、ActiveRecord without Rails で試してみました

  • Rackの上で動かす grape.ru を作成
require 'grape'
require 'active_record'
require 'sqlite3'
require_relative 'app/api/simple_api'
require_relative 'app/models/todo'

use ActiveRecord::ConnectionAdapters::ConnectionManagement
ActiveRecord::Base.configurations = YAML.load_file('config/database.yml')
ActiveRecord::Base.establish_connection(:production)

run SimpleApi

この grape.ru を指定し unicorn 起動

Framework Requests per second
Grape 56.65

Ruby on Rails に比べ 1.6倍の性能が出ました!

結論

テスト中のサーバーのメモリー使用量も調べてみました。実メモリ使用量(RES)は Ruby on Railsに比べると半分以下です。

Framework Requests per second VIRT(memory) RES(memory)
Grape within Rails 33.66 345308 91828
Ruby on Rails 34.49 345308 91828
Grape 56.65 253472 38852

結論としては、grape を使って API サーバーを作るなら Rackベースで起動し、 Ruby on Railsとは別に動かした方が良い。

ただし、開発時は Ruby on Railsの中で動かした方が開発しやすいかも知れませんね。

開けましておめでとうございます。本年もEY-Officeをよろしくお願いいたします。

2015年、開けましておめでとうございます。

本年も吉田裕美ならびに、EY-Officeをよろしくお願いいたします。お正月休みに考えた事を少し書いてみました。

f:id:yuum3:20150105103907j:plain

すし処佐治のおせち料理

EY-Officeの歴史を振り返った

2000年に長年勤めたCADのベンチャー企業から独立し EY-Office という会社を作り1人で仕事を始めました。開発や教育の仕事自体は私一人で行っていますが、お金の面を中心に大塚絵理さんに助けてもらっている2人の会社です。

もう独立してから、15年に成ろうとしています。そこで簡便的に5年に区切りまとめてみます。

2000〜2004年

独立し開発を始めたとはいえ、実はお仕事の殆どは一つの会社から受託していました。以前行っていたCADの開発とはまったく違うWeb系の仕事で色々な事を学ばせて頂きました。そして、その会社の売り上げの中心になるサービースのWeb Application Framework を作りました。CADの会社でもCADのベースになる図形データを扱う基本部分を作ってきた経験が生かせ、その会社の社長の経験や発想を混ぜたユニークなフレームワークが出来たと思っています。

また、Perl言語を使って開発していたので Perlのコミュニティーである Shibuya.pm に参加し、色々な方と知り合えたり、他の技術系のコミュニティー(例えば Seasarプロジェクト) などにも参加するようになっていきました。

2005〜2010年

一つの会社から受託していると その会社の経営状況に依存します、またコミニュティーなどを通じて得た新しい技術を試すことも出来なくなります。

そして一つの会社の仕事を行っていると、サラリーマンとそれほど変わらない立場、メンタルになってしまします。そこで、コミニュティーなどを通じて知り合った方などに紹介して頂いた新しい会社とのお付き合いが始まりました。

この時期にEY-Officeにとって大きな事がおきました。一つは、開発でお付き合いのあった会社から「教育」を行ってくれないかという依頼があり、コミニュティーの学んだスタイルを元におそるおそる教育を行ってみました。 長年開発しかしてこなかったので、講師としての能力の低さを痛感しながらも教えるのは面白いなと感じました。

さらに、空前のRuby on Railsブームが起こり、キャッチアップするために Rails勉強会@東京 に参加するようになりました、超出来るプログラマー達が集まる勉強会はとても刺激的でした。そして何回か参加する頃から初心者向けのセッションを行うようになっていきました。これが現在の EY-OfficeのRuby on Rails教育へと繋がって行きました。

2010〜2014年

Ruby on Rails教育 はEY-Officeという会社としての初めてのビジネスだったのかも知れません。しかし営業力もなく、Ruby on Railsブームも開発者だけでの盛り上がりで教育ビジネスでだけで食べて行くことはできず、受託開発も行いながらたまに教育を行うというスタイルが続きました。ただし、2012年頃から経営層にもRuby on Railsが届いたようで、大企業からも教育の注文が来るようになってきました。

しかし教育の仕事を絶えず取るのは難しいです、しばらく仕事絶えてしまう事もありました、そんなあるとき iPhoneMacも持っているのだからiPhone開発でもやってみるか! という感じで勉強でアプリを作ったり、受託でアプリを作ったりしました。 iPhoneの開発情報は当初NDAで保護されていた事もあり開発コミニュティー等が少なかったのですが、ある時期から勉強会が始まり参加するようになりました。 自分が勉強して来た事は教育コンテンツとして教えられると判っていたので、iPhone開発の教育も始めました。ある時期はかなり需要がありましたが、現在はあまり需要がないようです。

仕事が絶えてしまった時にコミニュティーで知り合った方から仕事を頂いたり、たくさんの方のおかげで何とかやっている状況でした。

さて今年はどうしようか

昨年は、このブログ、会社のホームページ 開発の仕事を募集したのですが、ほぼありませんでした。教育の仕事はある程度あるのですが、夏は暇で(Docker, Node.js,Swift,Go..など)たくさんのお勉強をする時間に恵まれてしまいました ^^;

昨年末に、以前お世話になった方から小規模の開発の仕事を頂きました。その方と話をしていた時に、受託はどうしてもお客様に依存してしまうので、やはり自社で何かビジネスをしないとダメなのではと言われました。

また最近はベンチャーがたくさん立ち上がって来ていますが、最初から開発者を抱えて自分たちのビジネスを育てています。以前に比べると技術者の流動化は高まっていて、魅力的なビジネス・経営者であれば優秀なエンジニアをリクルートしやすくなり、フリーの技術者に頼る必要性が下がってきたのかも知れません。 開発会社としてのEY-Officeや開発者としての吉田裕美というのは知名度が低すぎマーケットに届いていないと思います。

そこで、今年はどうするかですが、

  • 教育ビジネスも力を入れて行っていきます。
  • 受託の開発案件も引き続き探します、よろしくお願いいたします。
  • 今のところ、自社サービスやアプリの目処はないですが、今年はあいている時間で思いついた、小さなアプリやサービスをリリースしていきたいと思います。少しずつアイデアを貯めています・・・・
  • 頂いた仕事は、開発も教育も自分の力を出し切りがんばって行きます。

さらに個人的には

  • 英語力の無さを痛感しています。挨拶程度の会話は出来ますが、現在は issueを書いたり質問をしたり出来る能力が不足しています。中学校2年くらいですでに英語を捨てていたの単語力や基本的な文法力がありません。先ずはこの辺をクリア出来るようにしたと思います。
  • 歳をとり体力が落ちています、近くの公園でのジョギングを毎週おこなうように心がけます、昨年も時々行っていたのですが、ついつい行かない時期がありました。

結論

お仕事募集中です !

本気のiOS開発者は読むべき一冊「UIKit徹底解説 iOSユーザーインターフェイスの開発」

入門書や入門講座などを終わり、これから本気でiOSアプリを作るぞ! と思っているいる人は買うべき一冊です。またiOSアプリを一つ二つ作った人も「なるほど!」と思うUIKitの知識が詰まっています。

内容はiOS7用に書かれているので iOS8で導入された機能やSwift言語には対応していませんが、ここに書かれている内容は iOS8でもほとんどが使えます。また SwiftiOSアプリを書く場合もUIKitは同じですから、ほんの少しの脳内コード変換で使えます。

電子書籍も買えるのが嬉しいですね (Kindle以外に PDFも 達人出版会から買えます)

この本の読み方

問題解決

最初から読む必要はありません。テーマー毎にチャプターになっていますので、興味のあるところ、今作っているアプリが思うように動かない時に関連しそうなチャプターを読むと良いと思います。

内容は、かなり細部まで書かれています。 特に自分の作っているアプリのUIが思っているように動作しない時や、他のアプリで実現されている機能がどうやったら実現できるのか判らない時には StackOverflow や Qiita のような回答そのものではなく、iOSの原理や設計思想などの基本部分に付いても学べます。

スキルアップ

ネット上の情報には偏りがあります。また、UIに付いての解説はたくさんの概念図やスクリーン画像、適切なサンプルコードが必要になるので日本語での良質な情報はネット上には少ないと思います。

本書のような本を読むことは、自分の中で欠けている知識の補足になりますし、あらためてiOSの原理や設計思想などの基本部分を学ぶ事で開発力を高める事ができます。

また、分かりにくい Text Kit や UITableView、UICollectionView の高度な使い方も解説されています。