目前分類:其他技術資訊 (12)

瀏覽方式: 標題列表 簡短摘要

Homebrew 是一套在 Mac OS X 下使用的套件管理工具,以往大家會使用 Mac Ports ,但是 port 的套件相依性太深,常常會為了裝個小套件而跟著裝上一堆用不到的相依套件,甚至造成套件版本衝突…… 因此 Homwbrew 甫一推出立刻受到大家的歡迎。

今天早上我剛好重裝 readline 套件,安裝完成後訊息提示我 readline 套件是 「keg-only」。我為了查出「keg-only」到底是指什麼意思,結果解開一連串的謎題,真相終於大白! Homebrew 的所有命名真的非常有邏輯~~

首先, brew 本身是釀造、釀酒的意思,會用這個字的原因是 homebrew 的安裝方式為下載 source code 回來做編譯,由於是在自己電腦做 local complie 編譯套件,所以這個工具叫做 homebrew 自家釀酒。

釀酒需要有配方 formula ,當你需要安裝套件時,流程就是下 brew 命令去根據配方 formula ,釀造出一桶(keg)酒來。所以 keg 指的是整個編譯完成的套件資料夾。

再來,放置套件的位置在 /usr/local/Cellar , Cellar 就是地窖,一桶一桶釀好的酒當然要存放在地窖裡囉!所以編譯完成的套件資料夾 keg 預設目錄在 /usr/local/Cellar 。

最後回到「keg-only」這個詞,字面上意思現在就很清楚,表示這個套件只會存放在桶子裡,不會跑出桶子外;實際上的行為是 brew 不會幫你做 symlink 到 /usr/local ,避免你的原生系統內還有一套 readline 而打架,所以訊息提示說 readline 套件是 keg-only 。

至此謎題全部解開啦! Homebrew 的命名邏輯真是超有趣的~

 

相關連結:

Homebrew: 新一代 OSX 套件管理工具
Homebrew: OS X’s Missing Package Manager

Homebrew 專案頁面: http://mxcl.github.com/homebrew/
Homebrew 原始碼: https://github.com/mxcl/homebrew

文章標籤

笨笨小蟹 發表在 痞客邦 留言(7) 人氣()

有些時候需要撈資料,找出重複的記錄,但 Ruby Array 本身沒有這種功能的 method ,所以就自己打開 class Array 加進去吧!

class Array

  def find_dups
    uniq.map {|v| (self - [v]).size < (self.size - 1) ? v : nil}.compact
  end

end

參考資料:http://snippets.dzone.com/posts/show/4148

笨笨小蟹 發表在 痞客邦 留言(0) 人氣()

會使用到 Jammit gem 的原因是,我發現網站在 6 月改版後,就常常會發生網站脫衣服(吃不到 css)的狀況,而且都是在上班時間。

翻 log 查到原因後發現,原來是因為原本網站的伺服器只有一台,改版時調整成兩台並且做 HA ,問題就出在多台伺服器上。

Rails 的 layout 中, stylesheet_link_tag 我有設定 :cache => :merge_index ,因此看原始碼時會發現,網站只有讀取 merge_index.css ,這段設定就是請 Rails 幫忙把數隻 css 壓成一隻,減少 http request 的數量。

 

問題來了,這隻 merge_index 會在瀏覽器訪問頁面時檢查是否存在 /public/stylesheets 資料夾,如果不存在就先產生它,因此在 production 環境的目錄內你會找到 merge_index.css 這個 development 環境沒有、也不在 repository 內的檔案。

以上的狀況,當你只有一台伺服器時,一切都正常;當有多台伺服器時,就會發生瀏覽器問到還沒產生 merge_index.css  的伺服器,因而吃不到 css 造成脫衣服的問題。

這個問題同樣也出現在T客邦網站,因此 xdite 寫了一篇文章介紹 Jammit 來解決這個問題,解決就是 preheat CSS/JS。但實際套用後發現,並不能照著 xdite 的文章實作,那要怎麼寫呢?

 

首先要編輯 config/assets.yml ,這個 yml 檔案的最前面是關於 Jammit 的設定,詳細的設定清單比方說壓縮方式、gzip、路徑等等可以去看參考文件

注意,設定中記得要有加入這行,否則在 Jammit package 時,會告訴你無法產生 css (IE7 以下 MHTML issue)。

embed_assets: datauri

 

接著是設定 stylesheets 和 javascripts ,範例如下

stylesheets:
  commons:
    - public/stylesheets/reset.css
    - public/stylesheets/common-use.css
    - public/stylesheets/hf.css
    - public/stylesheets/right-column.css
  merge_diary:
    - public/stylesheets/diary.css
    - public/stylesheets/openid-comment.css

javascripts:
  commons:
    - public/javascripts/pop.js
    - public/javascripts/facebox.js
    - public/javascripts/jquery.timers-1.2.js
  merge_index:
    - public/javascripts/jquery.scrollTo-1.4.2-min.js
    - public/javascripts/jquery.easing.1.3.js
    - public/javascripts/jquery.serialScroll-1.2.2-min.js
    - public/javascripts/slideshow.js

以範例來說,到時候產生出來的就會有 commons.css, merge_diary.css, commons.js, merge_index.js ,每隻檔案要包含哪些 css/js 就是在 yml 內設定,相當直觀。

ps. 實際上,因為有設定 datauri ,所以檔案名稱還會後綴 -data-uri ,此處為了直觀故省略了後綴字。

 

接著,要去修改 layout 中使用 stylesheets 和 javascrpits 的方法,寫法是

<%= include_stylesheets :commons, :merge_diary %>
<%= include_javascripts :merge_index, :commons %>

 

最後,因為網站需要 preheat stylesheets 和 javascripts ,在 capistrano recrips 內需要加上

before("deploy:symlink") do
  run "cd #{release_path} && bundle exec jammit"
end

 

做完 preheat CSS/JS 之後,就不會在出現網站脫衣服的狀況囉!

笨笨小蟹 發表在 痞客邦 留言(0) 人氣()

記錄幾個好用的 tmbundle ,可以幫助整理 coding style 。

首先是小技巧,要設定 TextMate 使用 tab 時的對應字元,就在視窗的最下方,有個顯示 Soft Tabs: 2 或是 Tab Size: 4

我的團隊是使用 space 2 做為 indent ,所以是設定 Soft Tabs: 2 。

 

其次是,常常會發現有些檔案拉下來排版亂掉,可能是來自美術,或是手誤沒排好等等,可以裝 code-beautifier.tmbundle

操作方法是按 alt+cmd+b 你就會看到亂掉的程式碼,被重新整理好 indent 啦!

 

最後,你常常會不小心在行尾多了一些空白,可以裝 whitespace-tmbundle

用法完全無痛,因為他取代了存檔熱鍵 cmd+s ,只要存檔就會自動清潔所有的 trail whitespace ,讚!

笨笨小蟹 發表在 痞客邦 留言(0) 人氣()

在 rails 的專案內設定 .gitignore ,忽略掉 config/database.yml ,但是卻一直出現在 changed status 上。

這問題以前遇過一次,但是忘了記錄下怎麼解決,這次來寫解法。

reference:
http://stackoverflow.com/questions/3296739/git-not-ignoring-certain-xcode-files-in-gitignore

這種狀況是,之前有不小心把該檔案 commit 進 repo ,所以無法忽略,要下

git rm --cached your_filename

然後 commit 去更新 repo ,這樣 gitignore 就會生效啦!

文章標籤

笨笨小蟹 發表在 痞客邦 留言(1) 人氣()

最近看到兩個很方便的 Ruby 網站。

http://tryruby.org/
可以直接在這邊嘗試 ruby 指令,不用安裝 ruby 就可以體驗~
不過我自己使用時,有時候結果會跑不出來 ><

http://www.rubular.com/
本人很不擅長寫 regular expression ,這個網站可以直接寫並且有 WYSIWYG 喔!
可以輕易地測試自己寫出來的正規表示式有沒有問題,能不能正確 work 。

2011/06/08 更新:
感謝 hSATAC 提供另一個 regular expression 的好站: http://gskinner.com/RegExr/

文章標籤

笨笨小蟹 發表在 痞客邦 留言(0) 人氣()

我在架設好 gitweb 之後,發現就算設定網站只有公司內部 ip 可以連線,但還是太過公開,但是又不想花心力去做帳密系統管理,請教朋友後他建議利用 htpasswd 就能輕鬆達成我的需求。

htpasswd 是 apache 套件附上的一個功能,可以做出基本的使用者認證。
htpasswd 的詳細指令可以參考這篇文章: htpasswd - 管理用於基本認證的用戶文件

 

產生帳密檔案:

cd /home/git/gitweb
htpasswd -cb 檔名 帳號 密碼
htpasswd -b 其他帳號 密碼

其中參數 c 是建立檔案,只有第一次產生時需要。修改密碼也是一樣的指令,就會覆蓋掉原本檔案內的字串。

設定 nginx :

找到 gitweb 的 server 設定區塊,到 location / 中的最前面加上

location / {
   auth_basic "Yoursite Gitweb";
   auth_basic_user_file /home/git/gitweb/htpasswd檔名;
   ...
}

完成後執行 /etc/init.d/nginx restart ,連到 http://gitweb.yoursite.com.tw ,就會出現要求輸入帳號密碼囉!

 

延伸閱讀: 架設 gitweb with nginx

笨笨小蟹 發表在 痞客邦 留言(1) 人氣()

如果你的網站是利用 github 來做管理,那這篇對你大概沒什麼幫助,因為 github 通通都幫你做完啦!

最近我負責的專案需要改版,考慮到寫程式的人不再是只有我一個,決定來把 git web 介面弄起來,就可以直接在瀏覽器看 git repositories。

前提:
假設你已經用 gitosis 架設好你的 git server。
我的機器是跑 Debiannginx web server。

架設 PHP-FastCGI
如果機器一開始就是打算跑 Ruby on Rails ,那上面很可能會沒有 phpperl 環境,但是我使用的架設方式跑 fcgi ,所以需要先完成這個步驟。

參考文件: PHP-FastCGI with Nginx - Nginx and PHP-FastCGI on Debian 5 (Lenny) - Linode Library

1. 先安裝套件

apt-get update
apt-get upgrade
apt-get install php5-cli php5-cgi libfcgi-perl psmisc gitweb

2. 安裝 spawn-fcgi ,如果 spawn-fcgi 網站有釋出新版本請自動換掉下面的程式碼

cd /opt
wget http://www.lighttpd.net/download/spawn-fcgi-1.6.3.tar.gz
tar -zxf spawn*
cd spawn*
./configure
make
cp src/spawn-fcgi /usr/bin/spawn-fcgi

3. 讓 php-fastcgi 跑起來,完成後可以 ps aux 檢查一下

cd /opt
wget https://library.linode.com/web-servers/nginx/php-fastcgi/reference/php-fastcgi-deb.sh
mv php-fastcgi-deb.sh /usr/bin/php-fastcgi
chmod +x /usr/bin/php-fastcgi
wget https://library.linode.com/web-servers/nginx/php-fastcgi/reference/php-fastcgi-init-deb.sh
mv php-fastcgi-init-deb.sh /etc/init.d/php-fastcgi
chmod +x /etc/init.d/php-fastcgi
update-rc.d php-fastcgi defaults
/etc/init.d/php-fastcgi start

4. 設定 nginx

# /etc/nginx/nginx.conf
server {
  listen      80;
  server_name gitweb.yoursite.com.tw;

  access_log /var/log/nginx/gitweb.access.log;
  error_log  /var/log/nginx/gitweb.error.log;

  # First rewrite rule for handling maintenance page
  if (-f $document_root/system/maintenance.html) {
      rewrite ^(.*)$ /system/maintenance.html last;
      break;                                                                                                 
  }

  location / {
     fastcgi_pass 127.0.0.1:7000;

     fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
     fastcgi_param QUERY_STRING $query_string;

     fastcgi_param REQUEST_METHOD $request_method;
     fastcgi_param CONTENT_TYPE $content_type;
     fastcgi_param CONTENT_LENGTH $content_length;
     fastcgi_param REQUEST_URI $request_uri;
     fastcgi_param DOCUMENT_URI $document_uri;
     fastcgi_param DOCUMENT_ROOT $document_root;
     fastcgi_param SERVER_PROTOCOL $server_protocol;
     fastcgi_param GATEWAY_INTERFACE CGI/1.1;
     fastcgi_param SERVER_SOFTWARE nginx;
     fastcgi_param REMOTE_ADDR $remote_addr;
     fastcgi_param REMOTE_PORT $remote_port;
     fastcgi_param SERVER_ADDR $server_addr;
     fastcgi_param SERVER_PORT $server_port;
     fastcgi_param SERVER_NAME $server_name;
  }

  location /static { root /home/git/gitweb; }

接著,我是到 git 帳號的家目錄下 mkdir gitweb,把 /usr/share/gitweb 裡面有三個檔案都複製到 /home/git/gitweb/static/ 。

5. 設定 gitweb

# /etc/gitweb.conf

# path to git projects (<project>.git)
$projectroot = "/home/git/repositories";
 
# directory to use for temp files
$git_temp = "/tmp";
 
# target of the home link on top of all pages
#$home_link = $my_uri || "/";
 
# html text to include at home page
$home_text = "indextext.html";
 
# file with project list; by default, simply scan the projectroot dir.
$projects_list = "/home/git/gitosis/projects.list";
 
# stylesheet to use
$stylesheet = "/static/gitweb.css";
 
# logo to use
$logo = "/static/git-logo.png";
 
# the 'favicon'
$favicon = "/static/git-favicon.png";
 
# A list of base urls where all the repositories can be cloned from.
# # Easier than having per-repository cloneurl files.
@git_base_url_list = ('git+ssh://git@yoursite.com.tw');

6. 設定 gitosis

我有設定 gitosis-admin.git ,直接編輯 gitosis.conf ,再 git push 更新設定。
記得 repo, owner, description 都要改成自己的。 

# gitosis.conf

...
[repo your-repository]
gitweb = yes
owner = wildjcrt
description = "Your repository's description"
...

7. 製作 gitweb.fcgi 執行檔

把下面這對程式碼全部複製後儲存,我是存到 /home/git/gitweb/gitweb.fcgi ,然後 chmod +x gitweb.fcgi 。

#!/usr/bin/perl -w

use strict;
use FCGI;
use CGI;
use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/;

sub usage {
       print STDERR "$0 --fcgi-socket=(path|[host]:port) ",
                    "--cgi-bin=path\n";
       exit 1;
}

my ($fcgi_sock, $cgi_bin);
GetOptions('fcgi-socket|s=s' => \$fcgi_sock,
           'cgi-bin|c=s' => \$cgi_bin) or usage();

usage() unless ($fcgi_sock && $cgi_bin);

die "FastCGI socket: $fcgi_sock already exists!\n" if (-S $fcgi_sock);
die "CGI executable: $cgi_bin does not exist!\n" if (!-f $cgi_bin);

# gitweb will exit, make it throw an exception instead:
no warnings qw/once/;
*CORE::GLOBAL::exit = sub { die 'gitweb_exit' };
use warnings;

# FCGI will erase the current %ENV; so make sure we save this:
my $gwcfg = $ENV{GITWEB_CONFIG};

my $fcgi_req = FCGI::Request(\*STDIN, \*STDOUT, \*STDERR, \%ENV,
                             FCGI::OpenSocket($fcgi_sock, 128),
                             FCGI::FAIL_ACCEPT_ON_INTR);
while ($fcgi_req->Accept >= 0) {
       unless ($ENV{PATH_INFO}) {
               # nginx currently fails to set PATH_INFO,
               # so we'll do it ourselves
               my $pi = $ENV{SCRIPT_NAME};
               $pi =~ s!^/\+!!;
               $ENV{PATH_INFO} = $pi;
       }
       # clear CGI query parameters set inside gitweb so we can reparse
       # the %ENV fed to us
       CGI::initialize_globals();
       $ENV{GITWEB_CONFIG} = $gwcfg if defined $gwcfg;
       do $cgi_bin;
       delete $ENV{PATH_INFO};
}

END {
       unlink $fcgi_sock if (defined $fcgi_sock && -S $fcgi_sock);
}

8. 建立 start-gitweb.sh

跟步驟7類似,我是存到 /home/git/gitweb/start-gitweb.sh ,然後 chmod +x start-gitweb.sh

/home/git/gitweb/gitweb.fcgi --fcgi-socket=127.0.0.1:7000 --cgi-bin=/usr/lib/cgi-bin/gitweb.cgi &

最後跑 ./start-gitweb.sh , ps aux 檢查一下,沒問題的話到 http://gitweb.yoursite.com.tw 應該就可以看到你的 git repositories 囉!

 

延伸閱讀: 在 gitweb 網站上加入簡單的 htpasswd 帳號管理

 

參考文件整理:
Pro Git - Pro Git 4.6 服务器上的 Git 网页界面 GitWeb
Pro Git - Pro Git 4.7 服务器上的 Git 权限管理器 Gitosis
Debian Linux 架設 Gitweb | Tsung's Blog
PHP-FastCGI with Nginx - Nginx and PHP-FastCGI on Debian 5 (Lenny) - Linode Library
Gitweb with gitosis & nginx HowTo

笨笨小蟹 發表在 痞客邦 留言(1) 人氣()

因為最近剛好需要做報告,遇到了這個困擾。平常在 TextMate 看程式碼都上好顏色了,看的非常習慣,但是做投影片時要怎麼把顏色搬上去呢?

一開始 google 到 copy to rtf 這個 bundle,但是實際試用後發現有 bug 沒有解決(前景顏色被忽略、Ruby 1.9 會有問題),所以就繼續找下去,最後找到完美的解決方案,就是 Copy with Style Textmate bundle 。

安裝方法很簡單,複製貼上就好了(當然要先裝好 git),複製指令是 Cmd+Shift+C ,貼上則一樣是 Cmd+V 。

貼上之後的效果非常完美!這個 bundle 真是太棒了。

注意:這個複製會完全比照你看到的顏色,所以像筆者的 TextMate 使用黑色背景,那 Keynote 得一樣用黑色。

 

這邊附上製作過程,文章在此:Copying Code from Textmate to Keynote with Style
然後,作者是根據此篇文章而製作出 bundle:TextMate to Keynote in 2 steps

笨笨小蟹 發表在 痞客邦 留言(0) 人氣()

雷超大orz

http://github.com/kingpong/ruby-mcrypt

sudo port install libmcrypt +universal

然後先做 symbolic link 把 libmcrypt 連結到 /opt/local
這個步驟忽略的話,下一步的路徑就要指對~

ln -s /opt/local-backup/var/macports/software/libmcrypt/2.5.8_1/opt/local/  libmcrypt(我本機這樣下,但每人電腦或有不同請自行修正~)

sudo gem install kingpong-ruby-mcrypt --source=http://gems.github.com -- --with-mcrypt-dir=/opt/local

然後我用起來,不需要require 'rubygems'

ps. 我這台是ree, gem 1.3.2

笨笨小蟹 發表在 痞客邦 留言(0) 人氣()

今天因為測試 css 的 cache,但是跑 development 環境時,cache 並不會有作用,因為本機測試正常,打到 stage 機器上就爆炸了orz

但是這時候,你又已經做了 commit 並 push 到repository 上,要怎麼解決呢?

 

如果你知道是哪一項 commit 造成這個錯誤,可以下 git revert 把那項變更還原,但是如果說想從現在倒回到某次變動(比如倒回4次 commit ),今天學到一個方法。

首先指令下 git reset "某次 commit 的 SHA 值",這裡注意,給出的 SHA 值就會回到那次 commit 結束後的狀態。
例如 git reset a8b5a0afea1e1f5faccda4a698c0002bdcc7bf892

這樣 commit 的狀態就會回到該時間點,但是修改的內容還是目前最新的狀態,因此 git status 會發現這段時間 modified 過的檔案。
接著下 git checkout -f ,checkout可以幫你把更動過的檔案,回到最後一次 commit 時的狀態,所以檔案的狀態就會變成跟倒回的時間點相同。

最後下 git reset original/master,將 commit 的位置直接指向最新的地方,然後 commit 並 push ,就可以看到 repository 又回到你指定時間點的狀態,而且中間變動過的 commit log 也都還在!
注意一點,commit 指向的位置,可能隨著你的專案還不同,像我現在的位置是指向 production/master 。 

 

笨笨小蟹 發表在 痞客邦 留言(0) 人氣()

這次因為有些地方中文字儲存後會變成一堆問號 ???????????

所以發現 rake db:migrate 時會需要注意 collation 的問題。

確認的話,如果有裝 phpmyadmin ,事情很簡單,反正有介面可用找一找就可以知道結果。

如果沒裝得下指令的話,指令如下:

查看db
use db_name;
然後下 status 就可以看到 db 的 collation

查看table
一般查看 table 指令是下 describe table_name; 但是這不會出現 collation
所以要改下 show full fields from table_name;

參考網頁:MySQL 於 命令列 查看 Table 權限、註解等欄位資訊

 

治標的方法是 migrate 檔案內,直接指定 table 的 collation 校對格式,寫法如下:

create_table (:table_name, :options => 'ENGINE=InnoDB DEFAULT CHARSET=utf8')

 

如果 rake 指令已經下了,可以選擇回溯到某個日期的 migrate,指令為:

rake db:migrate VERSION=20100315074536
VERSION= 之後是 migrate 檔名開頭的 timestamp

 

如果不想回溯要直接改 collation ,指令是:

更改 db 的 collation
alter database db_name collate utf8_unicode_ci;

 

更改 table 的 collation
alter TABLE table_name CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

笨笨小蟹 發表在 痞客邦 留言(0) 人氣()