Bruce 的玩具間

my works and notes on ruby, rails, git, ubuntu linux, mac os x, etc...

Posts match “ Techbang ” tag:

超棒的 rails console 設定

| Comments

這篇文章現在搬到新站: 超棒的 rails console 設定

這篇是我閱讀 Using pry in production 後,結合我自己的經驗與公司前輩留下來的設定等,最後得出的一套組合。由於主題的關係這篇只介紹 rails console 相關的部分,實際上那套組合還有別的東西,以後若有機會再另外介紹。

ps. 依照 Using pry in production 的設定將會受到一個 readline 的 bug 影響,在 pry 解決該問題前,本篇有 workaround 教學。

想達到的效果

1. 預設漂亮的格式、還可以輸出 table

注意到 prompt 顯示出 project 的名稱,而不是預設的 "irb" 或 "pry",同時維護多個專案的話很實用。

2. 在 staging/production 的 rails console 會有明顯提示,防止手誤

...

(完整內容請到新站觀看 超棒的 rails console 設定)

在T客邦工作滿一年紀念

| Comments

今天正好是在T客邦工作滿一年。

這一年發生的事太多了,值得寫一篇紀念文

成長

去年我整個就是亂寫,知道的也不多,Ruby debugger, Capistrano, Unicorn 之類的東西也都只聽過沒用過。

這一年來除了接觸很多有的沒的工具(現在看來,都是很基礎的東西,但當時對我來說像天書...),甚至小事如 coding style 也有固定下來。

附帶一題,在T客邦會抓 coding style 問題,多一個或少一個不符合團隊習慣的空格都會被退回去修改。

今年也買了 Aeron 椅,加上「在公司登入 Facebook 測試帳號,就會懶得登入主要帳號」的政策(自己訂的),讓我每天的效率提升不少;以 2014年2月跟8月相比,RescueTime 花在 Software Development 類數據增加了 23%。

Aeron 椅的部分有寫了一篇文章:改坐 Aeron 椅提升工作生產力

回顧這段時間發的技術相關文章

有一些讀基礎文件的心得

也有因為不順手而進階研究了一些工具

也跑去參加一些上課、活動

希望今年也可以繼續學學新東西、寫寫部落格 XD

這一年在工作上最高興的成就

維護中的 rails projects (7個) RSpec 全都修成綠燈了

我應該跟不少人提過,我對現代軟體開發有三件事情很在意,分別是:

  • 程式碼版本管理
  • Issue tracking
  • 自動測試

在我進T客邦前,版本管理跟 Issue tracking 就已經有了,但各 projects 的測試都有幾個壞掉以致於不能跑完。

終於在滿一年之前幾個禮拜開始,把維護中的 project 的測試全部重寫,現在全都是 pass 狀態了。(不過 coverage 還很低,這是接下來這年的任務)

而且為了避免老是忘記跑 test 而逐漸敗壞,雖然沒有架 CI,但是有土砲一個「測試失敗就會中斷 deploy 流程」的機制。

新計畫

最近在準備一些新計畫,有些是會公開的,敬請期待。

Use codeclimate-test-reporter without a CI server

| Comments

For some reason, we didn't setup a CI server. But we still want Code Climate to know test coverage after each deployment.

After some searching and experiment. We came up with this solution.

1. Add Capistrano run_tests task

Because we don't have a CI server. We use Ben Dixon's run_tests technique covered in his book Reliably Deploying Rails Applications, which is:

lib/capistrano/tasks/run_tests.cap
namespace :deploy do
  desc "Runs test before deploying, can't deploy unless they pass"
  task :run_tests do
    test_log = "log/capistrano.test.log"
    tests = fetch(:tests)
    tests.each do |test|
      puts "--> Running tests: '#{test}', please wait ..."
      unless system "bundle exec rspec #{test} > #{test_log} 2>&1"
        puts "--> Tests: '#{test}' failed. Results in: #{test_log} and below:"
        system "cat #{test_log}"
        exit;
      end
      puts "--> '#{test}' passed"
    end
    puts "--> All tests passed"
    system "rm #{test_log}"
  end
end
config/deploy.rb
set :tests, ["spec"]
before :deploy, "deploy:run_tests"

It will run test before every deploy. And stop deploy process if there are any failed test.

2. Install and setup codeclimate-test-reporter

Install codeclimate-test-reporter by adding it into Gemfile

Gemfile
gem "codeclimate-test-reporter", group: :test

and run bundle install

Start the test reporter. Make sure that you put these lines at top of your spec_helper.rb.

spec_helper.rb
require "codeclimate-test-reporter"
CodeClimate::TestReporter.start

Manually tirgger fist test report (your project token can be found at Settings > Test Coverage)

(in terminal)
$ cd your_project_root
$ CODECLIMATE_REPO_TOKEN=your_token_here bundle exec rspec spec

It should show following message:

Coverage = xx.xx%. Sending report to https://codeclimate.com for branch master... done.

Now you should be able to see the report showing in Code Climate. Sometimes it can take a few minutes.

3. Modify run_tests and make it report after each deployment

When you run rspec without CODECLIMATE_REPO_TOKEN, even you have test reporter started, it won't send test report to Code Climate. In other words, you can control when to send report by giving token or not.

Modify the rspec command in lib/capistrano/tasks/run_tests.cap

I assume you always run complete test suit with this technique.

lib/capistrano/tasks/run_tests.cap
namespace :deploy do
  desc "Runs test before deploying, can't deploy unless they pass"
  task :run_tests do
    test_log = "log/capistrano.test.log"
    tests = fetch(:tests)
    tests.each do |test|
      puts "--> Running tests: '#{test}', please wait ..."
+      rspec_command = "bundle exec rspec #{test} > #{test_log} 2>&1"
+      rspec_command = "CODECLIMATE_REPO_TOKEN=#{fetch(:codeclimate_token)} #{rspec_command}" if fetch(:codeclimate_token)
+      puts "--> Running tests: '#{rspec_command}', please wait ..."
+      unless system(rspec_command)
-      unless system "bundle exec rspec #{test} > #{test_log} 2>&1"
        puts "--> Tests: '#{test}' failed. Results in: #{test_log} and below:"
        system "cat #{test_log}"
        exit;
      end
      puts "--> '#{test}' passed"
    end
    puts "--> All tests passed"
    system "rm #{test_log}"
  end
end
config/deploy.rb
set :codeclimate_token, your_token_here

Now, test will be run before every deployment and test report will be sent after that.

Note: you can put your token in run_tests.cap for simplicity. But I rarely commit any key or token into repostory. Instead, I put it in a git-ignored, separated config file. Than read and assign the value in config/deploy.rb.

在T客邦 新進工程師如何學習 Rails

| Comments

T客邦有許多優秀前輩經手並建立起來的 codebase 與 infrastructure、數個以維護為主的產品、不固定的新網站開發需求、已實行一段時間的軟體工程與專案管理方法等,因此在許多人眼中是不錯的 Rails 開發者練功環境。

也因此這是許多對T客邦工作有興趣的人會想知道的事,這次趁機會寫出來給大家參考,T客邦是個好溝通、氣氛佳、愛學習的團隊,歡迎來應徵。

但是,若抱著「我什麼都不會,但是我願意學習」的心態來應徵,恐怕機會是比較小的。如果有心,應該會展現在「我在某某線上課程完成多少課」、「我做過這個那個 side projects」或「我有個技術筆記分享部落格」等結果上,如果跟你競爭的應徵者多少有這類的成果可參考,那結果...你知道的。

這部分還可以參考我的另一篇文章 應徵 Rails 工作的心得

Rails 101 訓練

T客邦長期都使用 XDite 的教材 Rails 101 進行新人訓練,但一直有隨著時間進化,目前除了熟悉 Rails 功能、coding style,也會順便練習實際的工作流程。

  • 使用 Rails 101 的題目,但會加上一些限制,例如不准使用 scaffold generator
  • 負責帶新人的同事會用 Redmine 派票,也會要求養成回報到票上的習慣
  • Git 分支策略採用 GitHub flow,branch 名稱也有命名原則
  • 每個 PR 都會抓效能問題、不良的開發習慣、可改寫得更漂亮的地方與 coding style 等問題

這套練習還包含架設一台 Ubuntu server、用 Unicorn 跟 Capistrano 達到 zero-downtime deploy 等。

線上課程與文章

公司會要求的只有上述 Rails 101 的練習,其他的就只能看個人願意花多少時間學習/練習了。

所以觀看線上教學、閱讀 tutorial 或官方文件等都都是要自己去安排的。不過公司會補助一些線上課程的費用,例如 Code School, RailsCast, TeaLeaf 等。就算不在目前補助範圍內的,有需要的話也可以談。

另外就是工程師之間都會互相丟好文章連結、推薦不錯的書籍或 Leanpub 電子書等。最近復活的 Techbang 技術部 粉絲頁 前 20 幾則文章基本上都是從頻道紀錄裡撈出來貼的。

追程式碼與查資料

由於 Techbang 的許多專案都累積幾年了,有些架構不直覺可能是有原因的,因此接到某些票發現解法不單純的話,有可能需要追某個功能的所有相關 code、翻那段 code 的 git 修改歷史紀錄、找出對應的票並搞清楚當初設計的原因、繞過或處理歷史包袱等等。

有些功能則是沒有前例可查,但可以用關鍵字找網路上的範例或構想、查官方文件想辦法兜出解決方案、研究別人的 open source project 是如何實做的等等。

讀別人的 code、上網找資源兜解法,常常可以學到很多技巧、探索一些之前不知道的 API、library 或工具。

當然也不是派了票就放你自生自滅 生命會自己找到出路 ,有遇到問題都可以提出來討論,工程師前輩或熟悉業務邏輯的 PM 會很樂意提供意見。

T客邦目前使用的 code 品質輔助工具

| Comments

這篇介紹一下T客邦跟我個人有在使用的品質(尤其是 coding style)輔助工具,有些是我幫T客邦引入的,有些是我從T客邦現有的制度學來的。

RSpec

比起這篇要介紹的其他項目,測試算是不太一樣的類別,但它很重要。例如改 Apple modle 意外的搞爆 Banana controller 而不知,如果你沒寫測試,可能就會到上線後才知道。

小作業:去查 regression testing 跟 non-regression testing 是什麼

寫這篇的時候,T客邦的測試大部分還是很陽春的狀態,覆蓋率不高、寫法也沒有特別遵循一些已知的 guidelines,但即使是最基本的測試也可以享受到一些好處。T客邦的測試寫法還有很大個改善空間,就等優秀的你來應徵。(☉▽☉)

加入 Gemfile

Gemfile
group :development, :test do
  gem 'rspec-rails', '~> 3.0'
end

bundle install

跑 generator

rails generate rspec:install

先寫一個很陽春的 spec,改到 rspec 可以順利跑完為止

spec/controllers/posts_controller_spec.rb
require "rails_helper"

describe PostsController, type: :controller do
  describe "GET 'index'" do
    it "renders index template" do
      get :index
      expect(response).to be_success
    end
  end
end

之後再視需求追加測試、追加 gems (例如 capybara, faker, fabricator 等)。如果你的目標是確保執行路徑上不要有嚴重錯誤就好,可考慮寫 feature tests 為主。

如果你使用 capistrano 做 deploy,但沒有架 CI server 的話,可以參考 Use codeclimate-test-reporter without a CI server 把 run_tests 的 capistrano task 設定好,如此一來若有忘記跟著功能程式碼一起修改的 test 敗壞的話,就會阻止你 deploy。(這部分是學自 Reliably Deploying Rails Applications 一書)

Coding style, code smell 與 best pratices 工具

這幾個項目其實都不用寫在 Gemfile 內,但我習慣直接加進去,因為只要 bundle install 就都裝好了,且以後新人即使一開始不知道有這些 gems 可用、只要肯搜尋各個 gems 的用法就也會發現。

修改這些警告項目時,如果有不錯的測試覆蓋率將會增加修改的信心,反之就會很擔心會不會搞爆功能了、最後還是不敢動它。如果你維護的專案既沒有測試也沒有遵循 coding style,我會建議:

  1. 先修嚴重的問題,例如 brakeman 警告中,特別嚴重的安全問題
  2. 補一些陽春測試,確保執行路徑上不要有嚴重錯誤,並且跑不過就不准 deploy
  3. 之後再開始修次要 coding style

Brakeman

是用來偵測 Rails 寫法造成的安全性問題的工具。

Gemfile
group :development do
  gem 'brakeman', :require => false
end

bundle install

在 project 根目錄執行

brakeman

就會看到它提出的建議,似乎大部分建議也都可以在官方的 Ruby on Rails Security Guide 看到。

rails best pratices

是依照社群維護的 Rails Best Practices 提供寫法建議,常見的建議有:在 partial 內不要用 @instance_variable使用 render 的簡化寫法應該從 view 移到 model / controller / helper 的 code移除行尾空白 等。

Gemfile
group :development do
  gem 'rails_best_practices', :require => false
end

bundle install

在 project 根目錄執行

rails_best_practices

參考官方 README > Customize Configuration 把你確定不處理的警告關掉。

EditorConfig

是指定空行、換行 style 的編輯器外掛+設定檔。雖然各編輯器通常可以自己設定,但使用 EditorConfig 的好處是只要要求新人裝對應的外掛即可,不怕新人設定錯,而且設定可以跟著 project 走。

在 project 根目錄加設定檔

.editorconfig
# Please install EditorConfig plugin for your editor or IDE

# Usage and plugin list can be found here: http://EditorConfig.org


# top-most EditorConfig file

root = true

[*]
end_of_line = lf
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true

[*.md]
indent_size = 4

並到 EditorConfig 官方網站尋找你使用的編輯器,安裝相應的編輯器外掛。

幾個月前我第一次嘗試使用 EditorConfig 時發現 Sublime 的 global settings 會覆蓋掉 EditorConfig 的設定,但第二次嘗試時就正常了,不確定是誰 update 過。

rubocop

依照社群維護的 bbatsov/rails-style-guidebbatsov/ruby-style-guide 提供建議。常見的建議有各種縮排層級、空白、空行的位置/數量、統一使用單引號或雙引號(依照你的設定) 等非常詳細的 coding style 問題。

Gemfile
group :development do
  gem 'rubocop', :require => false
end

bundle install

在 project 根目錄執行

rubocop

就會看到修改的建議

參考 官方 README > Configuration 把不修正的警告關閉、與團隊現有 coding style 不符的地方改參數。另外也可以在誤判的程式碼前後加上特殊的註解即可小範圍排除特定的警告。

另外,Rubocop 具有自動修正的功能,我使用以下的流程(實際指令要去翻 README):

  1. 寫一個把所有 cop 都關閉的設定檔
  2. 寫一個繼承上述設定檔,並且 override 掉想修正的項目(但不是所有 Cop 都支援自動修正)
  3. 執行 Rubocop 的自動修正指令
  4. 回到第二步,改成下一種要修正的項目

可用的外部服務

這部分是一些可以幫你跑檢測工具,並透過較友善的介面回報給你的服務。

Hound

是 Rubocup + CoffeeLint + JSHint 的服務
且偵測到問題會自動在 Pull Request 上直接留言

計費方式

  • 12USD per project per month
  • 有 Open Source 可以自己架

Code Climate

是 Brakeman + 複雜度與重複性 的網路服務
其介面設計的很漂亮,且若有誤判可以從網頁介面隱藏掉(如果你自己跑 brakeman 的話,可能就要自己記住那個其實是誤判等等)

計費方式

  • 5 users x 5 private repos = 99USD per month
  • 16 users x 10 private repos = 199USD per month
  • 32 users x 20 private repos = 399USD per month

PullReview

還沒有認真的用,但初步看起來,使用方式跟 Code Climate 類似、功能較多,但計費方式不同。
功能似乎相當於有 Rubocop + Brakeman + 複雜度與重複性檢測,但底層是用誰目前不確定,支援 GitHub 跟 BitBucket。

  • 1 user x unlimited private repos = 20EUR per month

其實還有一些其他的服務,但因為我自己沒用過所以就不特別介紹了。

T客邦技術部的 20% 自由研究時間

| Comments

上禮拜趁機會向主管提出我考慮好一段時間的政策:20% 自由研究時間,意外的沒有遭到什麼反對,我們的主管很支持,也幫我們跟老闆溝通,於是今天就是第一次實行 20% 研究時間的日子。

為什麼要有 20% 的自由研究時間

Google 的 20% 自由研究時間,或者 Atlassian 的 FedEx day,是很有名的一項福利,在這段時間你可以做跟工作無關的事情、寫跟工作無關的 code,但其中偶爾會有成為公司主力產品的例子。

工作上勢必有些雜事、大家都不想做的苦差事、無聊差事等,為了讓公司順利營運,這些東西少不了,但一直讓員工做這些事的話,員工會不爽、會萌生離職念頭。

這就是為什麼我認為要有 20% 自由研究時間

  • 工程師會很興奮(工程師快樂是很重要的)
  • 可以幫公司內部做好用的工具(但這種東西一般是不會排進專案時程的)
  • 可能可以撿到公司下一隻金雞母業務

兩年前我有寫過一篇讀書心得,其中也有提到相關的話題:動機,單純的力量 重點與讀書心得

雖然聽說 Google 的 20% 自由時間已名存實亡,被員工酸是 120% 的工作時間,但我認為還是可以嘗試的,名存實亡的問題等公司跟 Google 一樣大再來擔心。

附帶一提,T客邦目前是上班打卡制、下班還是打卡制,時間到就好走了,最好不要賴在辦公室。

我們採用的規則

  • 每週五一整天(一週的 1/5 工作天 = 20%)
  • 放在禮拜五的原因是如果做開了,禮拜六日回家可以自己繼續做
  • 如果沒有想要做的主題,該週可以改成每天 20% 時間做小實驗,直到有明確的 idea 為止
  • 工程師不是機器,平常多少有狀況不好的時候,所以撥出 20% 時間其實不是很嚴重的事
  • 智慧財產權屬於公司

尋找題目

實行這樣的政策,有沒有題目作可能是維持下去的關鍵之一,如果大家都想不到要做啥,可能就會「啊算了、隨便啦」,就不了了之了。

我們找題目會從這幾個方向找

  • 公司非技術同仁提出他們面對的問題,例如 Facebook 留言抽獎的名單整理程式
  • 工程師自己在公司面對的問題,例如開發團隊 Dashboard
  • 與工作完全無關,解決自己私下面對的問題(但磨練技術最終還是會跟對公司貢獻有關)

一般來說,實做的成果能被使用(解決別人或自己的問題)、能獲得回饋(這邊如果改成…的話會更好)、受人肯定(這真好用耶!)就是不錯的題目。

示範成果

其實之前雖然沒有明文規定的 20% 自由研究時間,但工程師們本來就常常會找零碎時間做一些自動化的工具,以下兩個是我們之前做的小玩具。

Facebook 留言抽獎名單

是 Facebook 即將禁止的抽獎方式,不過當時常常有這樣的活動。

T客邦工程部 Dashboard

因為T客邦同時維護多個 Rails 網站,且都有一定的規模,加上有一些限制在,所以常常要多人對多個站平行做事、容易互搶主機,有 Dashboard 後就可以加速判斷是否搶到別人主機使用等。

另外也有待處理票的提示、開票自動化、各站的 coverage report shortcut 等方便開發者的功能。

在T客邦工作

T客邦目前還有 Rails 職缺,歡迎對 20% 自由研究時間會感到興奮的人來應徵:(工程師魂!)

Rails Developer 數名 - T客邦 (城邦文化事業股份有限公司) - Inside Job Board

另外也可參考 新進工程師如何學習 Rails 了解在T客邦可能的學習之路。