開發(fā)環(huán)境:如何使用 Ruby 工具鏈統(tǒng)一開發(fā)環(huán)境?

前言

在 iOS 開發(fā)過程中,會經(jīng)常遇到以下情況:

每次打開一個新項目,都需要手動搭建開發(fā)環(huán)境;有時候在安裝第三方工具時使用到 sudo 權限,導致以后安裝工具都需要手工輸入密碼而無法實施自動化。還有,每當啟動一臺新 CI 時,就需要手工登錄并配置一遍,更可怕的是,原先搭建好的 CI 會隨著 Xcode 版本更新需要重新配置。

為什么會這么麻煩呢?就是因為在項目開始之初沒有做好統(tǒng)一配置。

所謂統(tǒng)一配置,就是所有的配置信息都以文本的格式存放在 Git 里面,我們可以隨時查看修改記錄,以此來幫助我們比較不同配置之間的差異性,然后在這個基礎上不斷更新迭代。

可以說,有了統(tǒng)一配置,任何工程師都可以搭建出一模一樣的開發(fā)環(huán)境,構建出功能一致的 App;有了統(tǒng)一配置,還可以讓我們按需延展 CI 服務,而不用任何手工操作。更重要的是,它還可以應用到各個類似的 iOS 項目中,極大地減輕了項目前期的搭建成本。

既然統(tǒng)一的配置那么重要,那么我們怎樣搭建統(tǒng)一配置的開發(fā)環(huán)境呢?

Ruby 工具鏈

我們可以通過 Ruby 工具鏈為整個項目搭建一致的開發(fā)和構建環(huán)境。為什么選擇 Ruby 而不是其他語言環(huán)境呢?因為在 iOS 開發(fā)方面,目前流行的第三方工具 CocoaPods 和 fastlane 都是使用 Ruby 來開發(fā)的。特別是 Ruby 有非常成熟的依賴庫管理工具 RubyGems 和 Bundler,其中 Bundler 可以幫我們有效地管理 CocoaPods 和 fastlane 的版本。

下面一起來看看怎樣搭建一個統(tǒng)一的開發(fā)環(huán)境。


開發(fā)環(huán)境統(tǒng)一配置圖

通常,統(tǒng)一的開發(fā)環(huán)境應該從操作系統(tǒng)開始。對于 iOS 開發(fā)來說,MacOS 是目前 iOS 開發(fā)唯一支持的操作系統(tǒng)。在公司,MacOS 的版本需要由 IT 部門或者開發(fā)部門統(tǒng)一管理和更新,但是目前很多公司略過了這步,但是這步對于搭建統(tǒng)一的開發(fā)環(huán)境十分必要。要注意,當公司統(tǒng)一更新了我們開發(fā)環(huán)境的 MacOS 版本以后,需要同時更新 CI 上 MacOS 的版本,以保持一致。

Xcode

位于 MacOS 上層的是 Xcode 和 rbenv。其中,Xcode 是 iOS 開發(fā)和構建工具,在同一個項目里,最好使用同一個版本的 Xcode 進行開發(fā)和構建,我們可以在項目的 README.md 文件標注 Xcode 的版本。


README示例

那怎樣才能保證每個人都安裝同一個版本號的 Xcode 呢?技巧就是不要到有自動更新功能的 Mac App Store 中下載 Xcode,而是到蘋果的開發(fā)者網(wǎng)站搜索并下載。

Xcode下載示例

有時候我們會同時開發(fā)多個項目,這樣有可能要安裝多個不同版本的 Xcode。如果你的機器有多于一個版本的 Xcode,此時需要特別注意,為了保證所使用的編譯器版本一致,在每次執(zhí)行自動化命令之前(如執(zhí)行bundle exec fastlane test),要先使用xcode-select -s來選擇該項目所對應版本的 Xcode。

比如說我的電腦上有多個 Xcode 版本,在開發(fā) App 時,每次執(zhí)行自動化命令之前都會執(zhí)行這樣一條命令xcode-select -s /Applications/Xcode12.2.app/Contents/Developer來選擇 App 項目所使用的 Xcode。這里的Xcode12.2.app就是我安裝的 Xcode 12.2 版所在的位置。

rbenv

有了版本一致的 Xcode 以后,因為后期我們會用到 CocoaPods 等第三方 Ruby 工具,為了自動化安裝和管理這些工具,整個項目團隊所使用的 Ruby 版本也必須保持一致。為此,我們就需要用到 Ruby 環(huán)境管理工具。

目前流行的 Ruby 環(huán)境管理工具有 RVM 和 rbenv。推薦使用 rbenv,因為它使用 shims 文件夾來分離各個 Ruby 版本,相對于 RVM 更加輕裝而方便使用。千萬注意,團隊內(nèi)部不要同時使用不同的 Ruby 環(huán)境管理工具,否則項目編譯會出錯。

rbenvRuby 環(huán)境管理工具,能夠安裝、管理、隔離以及在多個 Ruby 版本之間切換。要使用 rbenv,我們可以通過 Homebrew 來安裝它,下面是安裝 Homebrew 和 rbenv 的腳本。

//下載速度慢請鏈接VPN
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
brew install rbenv ruby-build rbenv-vars

一旦安裝 rbenv 完畢,需要把以下的設置信息放到你Shell 配置文件~/.zshrc里面,這樣能保證每次打開終端的時候都會初始化 rbenv

export PATH="$HOME/.rbenv/bin:$PATH" 
eval "$(rbenv init -)"

接著就可以安裝和設置項目的 Ruby 環(huán)境了。

cd $(PROJECT_DIR)
rbenv install 3.0.1
rbenv local 3.0.1

此處是把項目的 Ruby 環(huán)境配置為 3.0.1 版本。rbenv 會建立 一個叫作.ruby-version 的文件,該文件里面只保存一個版本號(例如3.0.1)的字符串。這個包含了版本號的文件可以用 Git 進行管理。如果要更新版本,可以通過rbenv local命令進行,每次更新也由 Git 統(tǒng)一管理,這樣就能讓其他開發(fā)者使用同一版本的 Ruby 開發(fā)環(huán)境了。

RubyGems 和 Bundler

RubyGemsBundler 主要是用來安裝和管理 CocoaPodsfastlane 等第三方工具。

具體來說,RubyGemsRuby 依賴包管理工具。在 Ruby 的世界,包叫作 Gem,我們可以通過gem install命令來安裝。但是 RubyGems 在管理 Gem 版本的時候有些缺陷,就有人開發(fā)了 Bundler,用它來檢查和安裝 Gem 的特定版本,以此為 Ruby 項目提供一致性的環(huán)境。

要安裝 Bundler,可執(zhí)行sudo gem install bundler命令進行,之后,再執(zhí)行bundle init就可以生成一個 Gemfile 文件,像 CocoaPodsfastlane 等依賴包,我們就可以添加到這個文件里面。

具體代碼如下:

source "https://rubygems.org"
gem "cocoapods", "1.10.1"
gem "fastlane", "2.184.0"

注意我們在gem命令里面都指定了依賴包的特定版本號,然后執(zhí)行bundle install來安裝各個 Gem。 Bundler 會自動生成一個 Gemfile.lock 文件來鎖定所安裝的 Gem 的版本,例如:

DEPENDENCIES
  cocoapods (= 1.10.1)
  fastlane (= 2.184.0)

為了保證團隊其他成員都可以使用版本號一致的 Gem,需要把 Gemfile 和 Gemfile.lock 一同保存到 Git 里面統(tǒng)一管理起來。

到此為止,已經(jīng)知道怎樣使用 Ruby 工具鏈配置一個統(tǒng)一的開發(fā)環(huán)境。但在真實的開發(fā)環(huán)境中,搭建環(huán)境只需要一個人來完成即可,其他成員只需要執(zhí)行以下腳本就能完成整套開發(fā)環(huán)境的搭建。

./scripts/setup.sh

下面是腳本的內(nèi)容:

# Tip VPN
tip_vpn(){
   echo '執(zhí)行本腳本請先連接VPN...........'
}

# cd $(PROJECT_DIR)
cd_work_path(){
    RUBY_VERSION_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
    echo "RUBY_VERSION_PATH is $RUBY_VERSION_PATH"
    cd $RUBY_VERSION_PATH/..
    pwd
}

# Install brew
Install_brew(){
   if ! [ -x "$(command -v brew)" ]; then
       echo 'install brew...........'
       /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
   fi
}

# Install rbenv
Install_rbenv(){
    if  ! [ -x "$(command -v rbenv)" ]; then
      echo "install rbenv ..........."
      brew install rbenv ruby-build rbenv-vars
    fi
}

# config rbenv environment variable
config_rbenv_envar(){
    zshrc_file="$HOME/.zshrc"
    write_content="export PATH=\"\$HOME/.rbenv/bin:\$PATH\"
    \neval \"\$(rbenv init -)\""
    if [ ! -f "$zshrc_file" ];then
        echo $write_content >> $zshrc_file
    else
        if ! cat "$zshrc_file" | grep "$write_content" > /dev/null;then
            echo $write_content >> $zshrc_file
        fi
    fi
}

# Install ruby use rbenv
install_ruby(){
    ruby_version=`cat .ruby-version`
    if [[ ! -d "$HOME/.rbenv/versions/$ruby_version" ]]; then
      echo "install ruby ..........."
      rbenv install $ruby_version;
    fi
}

# Install bunlder
install_bunlder(){
    if  ! [ -x "$(command -v bundle)" ]; then
      echo "install bundler ..........."
      sudo gem install bundler
    fi
}

# Install all gems(cocoapods,fastlane)
install_gems(){
    echo "install all gems ..........."
    bundle install
}

# Install all pods
install_pods(){
    echo "install all pods ..........."
    bundle exec pod install
}

# Tip VPN
tip_vpn
# cd $(PROJECT_DIR)
cd_work_path
# Install brew
Install_brew
# Install rbenv
Install_rbenv
# config rbenv environment variable
config_rbenv_envar
# Install ruby
install_ruby
# Install bunlder
install_bunlder
# Install all gems(cocoapods,fastlane)
install_gems
# Install all pods
install_pods

該腳本主要做了八件事情:

  1. 進入工程目錄;
  2. 安裝brew;
  3. 通過brew安裝rbenv;
  4. 配置rbenv環(huán)境變量;
  5. 通過rbenv安裝特定版本的Ruby開發(fā)環(huán)境;
  6. 通過RubyGems 安裝 Bunlder;
  7. 使用 Bundler 安裝 CocoaPods 和 fastlane 等依賴包;
  8. 最后安裝各個 Pod。

這樣,一個統(tǒng)一的項目環(huán)境就搭建完成了,接下來開發(fā)者就可以打開APP.xcworkspace進行開發(fā)了。

說完 Ruby 環(huán)境搭建以后,最后講下保證項目文件一致性的 .gitignore 文件。

.gitignore 文件

.gitignore 文件是一個配置文件,用來指定讓 Git 需要忽略的文件或者目錄。如果沒有 .gitignore 文件,項目成員可能會不小心把一些自動生成等無關重要的文件或者具有個人信息(例如 xcuserdata)的文件保存到 Git 里面。這就大大增加了查看 Git 修改歷史的難度。因此,在項目初期就配置一個合適的 .gitignore 文件,能減輕后續(xù)的管理工作。

如何創(chuàng)建 .gitignore 文件呢?

可以在 gitignore.io 里面輸入關鍵字,例如 Xcode,Swift 等,然后該網(wǎng)站會自動生成一個默認的 .gitignore 文件。


gitignore.io

總結

以上,通過 Xcode、rbenv、RubyGems 和 Bundler 搭建一個統(tǒng)一的 iOS 開發(fā)和構建環(huán)境。


總結腦圖

再次強調(diào)下,為了讓各個開發(fā)和構建環(huán)境能保持一致,需要把 .ruby-version、 Gemfile 和 Gemfile.lock 文件通過 Git 統(tǒng)一管理起來,并共享給整個項目團隊使用。

而且,由于開發(fā)環(huán)境已經(jīng)通過 Bundler 管理起來,今后,當使用各個 Gem 工具的時候,也需要使用 Bundler。例如在使用 CocoaPods 時要執(zhí)行bundle exec pod,以保證使用的是項目級別而不是操作系統(tǒng)級別的 Gem 工具。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容