環境無關的環境

2021-09-17 02:55:02 字數 4665 閱讀 5746

軟體開發過程中常常需要搭建各種環境:開發環境、測試環境,整合構建環境等等。乙個不可複製的環境是低效的根源,它引起的常見問題比如:

\ 產品只能在你的機器上編譯通過\

產品在你機器上執行正常, 可在測試環境中總是出錯\

新加入乙個專案成員,需要一天時間來為其建立開發環境\

把測試環境和整合環境遷移到另外一台伺服器上花了幾天時間\

這些問題的原因以及解決方案,在最新出版《the productive programmer》(卓有成效的程式設計師)中,neal ford給出了詳細的介紹。我們列舉幾種細化的方案,作為書中提到的「間接」、「規範性」等原則的實踐。

\ 試**決的問題:環境的各個部分散落在不同角落,不是少了這個就是少了那個,或不同機器上版本不一樣;環境配置依賴全域性環境變數或屬性,硬編碼的絕對路徑等。

\ 目標:機器環境雖然各有各的不同,但依然有可能建立乙個「環境無關的環境」。

\\ 關鍵是如何獲得當前路徑,如何確定根路徑,如何確保目錄結構。

\\ windows和unix都有內建的環境變數來表示當前路徑,分別是%cd%$pwd\

windows批處理指令碼中,還可以使用%~dp0%獲得指令碼所在路徑\

而在unix bash 指令碼中,則可以使用「pwd」,即獲得pwd命令的輸出\

makefile中, 也可以獲得shell命令的輸出, 比如this_dir = $(shell pwd)\

ant指令碼中, 內建的basedir屬性預設代表的是指令碼檔案所在的路徑\

%cd%%~dp0%的區別:

\%cd%是指令碼執行時的當前工作路徑,與指令碼所在位置無關\

%~dp0%則相反,是指令碼所在路徑,與執行時的工作路徑無關\

舉例來說,有如下內容的d:\\project\\run.bat

\

\echo %cd%\echo %~dp0%\
\

如果在d:\\盤根目錄下執行project\\run.bat,則輸出如下

\

\d:\\\u0026gt;project\\run.bat\d:\\\d:\\project\\\
\

一般來說%~dp0%%cd%更常用

\ 下面是乙個環境無關的makefile的例子(只列出了變數定義部分):

\

\proj_root=$(shell pwd)\include += $(proj_root)/include\lib += $(proj_root)/lib\
\

當然也可以根本不定義變數表示當前路徑,而直接以相對路徑的形式引用子目錄,和通過「..」來引用父目錄及兄弟目錄,然而顯式的變數定義提供了一層間接,你可以通過多種方式覆蓋它的預設值,從而適應不同的環境。參見後面的「預設值 + 使用者自定義屬性」。

\\ 如果總是需要引用某個根路徑的話,則可以使用環境變數來定義根路徑(參見後面的環境變數)。其實相對路徑配合固定的目錄結構,大大削減了對顯式定義根路徑的需求。

\ 前面makefile的例子可以改寫如下:

\

\ifeq \"$(origin proj_root)\" \"undefined\"\proj_root = you_should_firstly_specify_$$_in_your_environment_or_by_command_line\endif\\include += $(proj_root)/include\lib += $(proj_root)/lib\
\

保證目錄結構的固定,自然是使用配置管理系統。

\\ 這是乙個「規範性」或者「標準化」的問題。配置管理系統不只是放源**的,只要有配置管理需求或配置管理能帶來好處,或需要有唯一的官方**,都可以使用配置管理系統來管理;環境的配置檔案,環境本身,都可以置入配置管理之下。有些公司的版本控制系統只放源**,連測試**都分開另放,耗費很多精力來維護源**之外的文件。

\ 強制使用配置管理可解決固定的目錄結構的問題\

使用配置管理還可以解決丟三落四的問題\

自然也可以解決所用工具版本不一致的問題\

這裡有幾個常見的問題:

\ 大型的系統軟體如何處理,比如jdk、vc++編譯器等,是否也需要置入版本控制:這個基本不用,如果對其特定的版本有需求,可在指令碼中加入檢查其版本的邏輯,不滿足則提示並退出即可\

必須放在特定位置的檔案如何處理,比如某個檔案必須放在/etc目錄下:這個檔案還是可以放在配置管理下的目錄中,而在/etc下建立符號鏈結來指向它;並提供指令碼來幹這件事。\

\ 必要時使用環境變數來引用環境。全域性的環境變數可用作預設值,在指令碼中覆蓋它(基本上,這是「使用者自定義屬性」的乙個例項)。

\\ 這是建立「環境無關的環境」的核心機制。無論如何,環境要在不同機器上部署,總會需要修改某些配置,以適應宿主機器。然而前面我們提到,所有配置都已置入版本控制。如果我們直接修改,則每個環境中都會存在未提交的本地修改。這是我們不希望看到的,因為當我們公升級配置並更新到所有部署時,可能會產生衝突。這裡其實是兩個層面的問題:

\ 提供一種機制,當環境與預設配置不一致時,允許使用者修改\

使用者修改的檔案應避免與官方檔案更新的衝突\

先說第乙個。

\ 預設值當然可以直接定義在指令碼或配置檔案中。而多數常用的指令碼和配置系統都提供了使用者定義屬性覆蓋預設值的機制。比如:

\ windows批處理:set path=my_extra_path;%path%\

bash:export path=my_extra_path:$path\

ant:\u0026lt;property file=\"user.properties\"/\u0026gt; \u0026lt;!-- user.properties 中可定義任何後面引用到的屬性,以覆蓋其預設值--\u0026gt;\u0026lt;property name=\"src.dir\" path=\"$\" /\u0026gt; \u0026lt;!-- 定義\"src.dir\"的預設值--\u0026gt;

\ cruisecontrol:\u0026lt;property name=\"src.dir\" value=\".\" /\u0026gt; \u0026lt;!-- 定義\"src.dir\"的預設值--\u0026gt;\u0026lt;property file=\"user.properties\"/\u0026gt; \u0026lt;!-- user.properties 中可定義任何後面引用到的屬性,以覆蓋其預設值--\u0026gt;

\ 注意ant的屬性是唯讀的,先入為主。cruisecontrol的屬性則是後發制人。\

makefile則可以直接在命令列覆蓋檔案裡面定義的預設屬性。如覆蓋前面例子中的proj_root

make proj_root=/home/mike/project\

再說第二個。

\ 有乙個很簡單的解決辦法,就是把使用者自定義屬性置入單獨的檔案,並且不要把它提交到版本控制系統中(乙個理由是這一部分相對整個組織來說,不存在也不需要唯一的官方**)

\ 前面例子中的user.properties就是乙個使用者自定義屬性檔案,只存在每個使用者自己的機器上,不在配置庫中。在windows和bash指令碼中也可以類似處理:

\windows: call user_env.bat\

bash: source ./user_env.sh. ./user_env.sh\

隨之而來的乙個問題是,這個使用者相關的檔案應該放在何處。這裡其實約定好就可以了,比如當前路徑,根路徑,甚至user的home路徑都可以。

\\ 至此,這套東西在不同的機器上部署時,只要從版本控制系統中check out出來即可使用了。更進一步,還可以提供指令碼,即生成器,自動探測使用者的環境,來生成全套配置,類似rails生成應用框架那樣。\

其實,這是乙個規範性或標準性的問題。neal ford 在《卓有成效的程式設計師》中,用一章的篇幅詳述了各種解決方案,包括配置管理,符號鏈結等。除此之外,他還建議可以/應該使用虛擬機器來統一專案組的開發環境等。參見《卓有成效的程式設計師》第五章。\

另請參閱《cruisecontrol enterprise 最佳實踐 (3) : configuring cruisecontrol the cruisecontrol way》,是建立環境無關的持續整合環境的例項。\

\ [ thoughtworks實踐集錦(1)] 我和敏捷團隊的五個約定。

\ [ thoughtworks實踐集錦(2)] 如何在敏捷開發中做好資料遷移。

\ [ thoughtworks實踐集錦(3)] richclient/ria原則與實踐(上)、(下)。

\ [ thoughtworks實踐集錦(4)] 為什麼我們要放棄subversion。

\ [ thoughtworks實踐集錦(5)] 「持續整合」也需要重構。

\ [ thoughtworks實踐集錦(6)] mock不是測試的銀彈。

\

開發環境 生產環境 測試環境的區別

開發環境 程式設計師專門用於開發的伺服器,配置較隨意,為了開發除錯方便,一般開啟全部錯誤報告和測試工具,是最基礎的環境。開發環境的分支,一般是feature 功能 分支 測試環境 一般是轉殖乙份生產環境的配置,當乙個程式在測試環境工作不正常時,肯定不能把它發布到生產伺服器上的,是開發環境到生產環境的...

開發環境 測試環境 預發布環境 生產環境的區別

開發環境 測試環境 回歸環境 預發布環境 生產環境。下面說說我個人對這些環境的理解 1 開發環境 顧名思義,開發同學開發時使用的環境,每位開發同學在自己的dev分支上幹活,提測前或者開發到一定程度,各位同學會合併 進行聯調。2 測試環境 也就是我們測試同學幹活的環境啦,一般會由測試同學自己來部署,然...

軟體開發環境 開發環境 測試環境 生產環境的區別

原創 2016年06月13日 15 46 21 對於乙個剛進入公司的新人來說,在熟悉工作環境的時候,會聽著幾個 老人 在自己可視範圍之外或者輕鬆的討論著業務,其措辭拿捏精準,期間,涉及到一系列的概念,可能會讓你不覺明厲,暗嘆 高階,大氣,上檔次 有些術語,它既有官方稱呼,也有通俗叫法,對於不覺明厲的...