2012-03-19 27 views
43

TL; DRrbenv: Còn sống sót mà không gemsets

  • Đừng bận tâm với gemsets; nhiều phiên bản của một viên ngọc có thể được cài đặt đồng thời.
  • Khi cần, hãy chỉ định phiên bản cần thực thi sử dụng ký hiệu $ gem-based-binary _version_ args.
  • Sử dụng bundle exec khi bạn có Gemfile chỉ định phiên bản.
gem install rails -v 3.2.13 
rails _3.2.13_ new Project2 
cd Project2 
bundle exec rails server 

UPDATE: 2015-06-04

tôi đã viết câu hỏi này cách đây ba năm. Một phần, nó được dựa trên một giả định sai lầm, và một phần tình hình đã thay đổi kể từ đó. Với sự đánh giá cao về @indirect cho câu trả lời ban đầu của mình, tôi muốn gọi sự chú ý đến câu trả lời mới hơn của (ít được upvoted) của @ kelvin, tóm tắt ở trên.

Giả định sai của tôi: Chỉ có thể cài đặt một phiên bản duy nhất của một viên đá quý tại một thời điểm, do đó cần phải có gemets để cô lập không gian tên. Không đúng. Nhiều phiên bản của một viên ngọc có thể được cài đặt đồng thời. Lệnh gần đây nhất sẽ được sử dụng khi được gọi từ một dòng lệnh, trừ khi bạn có một Gemfile chỉ định ràng buộc phiên bản và gọi lệnh thông qua bundle exec hoặc chỉ định phiên bản làm đối số đầu tiên của nó.

Xem thêm How can I call an older version of a gem from the commandline? re: ký hiệu gạch dưới phiên bản.


gốc câu hỏi:

Tôi có nhiều dự án đi vào sử dụng các phiên bản khác nhau của Rails. Tôi có một quy trình làm việc (được mô tả bên dưới) để tạo các dự án bằng cách sử dụng các phiên bản đường ray cụ thể và giữ các dự án được tách biệt với nhau. Tôi muốn thử nghiệm với các quy trình công việc khác, đặc biệt, sử dụng rbenv thay vì RVM, nhưng không rõ làm thế nào để làm như vậy.

HỎI: các thực hành tốt nhất hiện nay để tạo đường ray nhiều dự án, từng sử dụng một phiên bản khác nhau của đường ray, khi đưa ra sử dụng rbenvbundler, như trái ngược với rbenv-gemset hoặc RVM là gì ?

SỬ DỤNG TRƯỜNG HỢP: Tôi có hai dự án đường ray, được gọi là ProjectA và ProjectB. ProjectA được phát triển bằng một phiên bản đường ray ("RailsA"), trong khi ProjectB sử dụng một phiên bản khác ("RailsB"). Làm thế nào để quản lý có cả hai phiên bản được cài đặt?

PHỤ LỤC GEMSETS: Khi tôi bắt đầu với phát triển Rails, tôi đã sử dụng RVM. Ngoài việc hỗ trợ nhiều, đồng thời cài đặt của ruby, RVM hỗ trợ có nhiều Named Gem Sets.Mỗi dự án có bộ sưu tập độc lập riêng của mình đá quý (bao gồm cả đường ray chính nó) gọi là gemset:

rvm gemset create RailsA 
rvm gemset use RailsA 
# RailsA. Note: My question is not version-specific. 
gem install rails --version 3.0 
rails new ProjectA 
cd ProjectA 
rvm --rvmrc use `rvm current` 
vi Gemfile 
bundle install 
cd .. 
## Now do the same for ProjectB 
rvm gemset create RailsB 
rvm gemset use RailsB 
gem install rails --version 3.2 
rails new ProjectB 
cd ProjectB 
rvm --rvmrc use `rvm current` 
vi Gemfile 
bundle install 

Lưu ý: rất tạo các thư mục dự án cần được thực hiện (IMHO) bởi một lệnh rails new sử dụng mong muốn phiên bản đường ray vì các tệp khung hình thay đổi từ phiên bản này sang phiên bản khác. (Có lẽ tôi nên xem xét lại tiền đề này?)

cách tiếp cận BUNDLER: Tôi đã chơi với việc sử dụng rbenv thay vì RVM, nhưng tôi không hiểu được quy trình làm việc một cách rõ ràng. Trong README.md, Sam Stephenson viết rằng "rbenv không ... quản lý gemets. Bundler là một cách tốt hơn để quản lý các phụ thuộc ứng dụng." Có một plugin (rbenv-gemset) để nhận được kết quả tương tự như đá quý của rvm, nhưng Sam rõ ràng ủng hộ bằng cách sử dụng Bundler thay thế. Thật không may, anh ta không giải thích về công việc sẽ trông như thế nào. Ngay cả trang web Bundler không kết nối rõ ràng tất cả các dấu chấm về cách tách biệt một dự án khỏi một dự án khác. Một số blogsandgists đến để giải cứu, cho thấy ~/.bundle/config tập tin sau đây:

--- 
BUNDLE_PATH: vendor/bundle 

(BTW, tôi không chắc chắn những gì mà "---" được về Các tài liệu làm cho không đề cập đến nó và nó doesn. dường như tạo sự khác biệt.)

Điều này mang lại hiệu quả cho mỗi đường ray dự án gemset của riêng nó, lưu trữ các gem trong ProjectX/vendor/bundle /. Trong thực tế, đường ray chính nó sẽ được (lại) được cài đặt ở đó, làm cho dự án hoàn toàn độc lập với phần còn lại của môi trường của tôi, một khi tôi chạy bundle install.

Nhưng con voi trong phòng là vấn đề về gà và trứng khi tạo thư mục dự án đường ray trong địa điểm đầu tiên !! Để tạo thư mục ProjectA bằng RailsA, tôi cần cài đặt đường ray (và nhiều phụ thuộc của nó) trước tiên. Nhưng khi tôi muốn tạo ProjectB, tôi phải chuyển sang sử dụng RailsB. Nếu không có đá quý, tôi phải làm một số nâng cấp/hạ cấp nghiêm trọng. Không mát mẻ.

Một giải pháp có thể đơn giản là không phải lo lắng về phiên bản đường ray nào tôi sử dụng để tạo thư mục ProjectX. Nếu sau đó tôi sử dụng đường ray 3.0 để tạo một dự án 3.2, tôi có thể tự tạo cây ứng dụng/tài sản. Nhưng điều đó chỉ làm tôi khó chịu. Không có cách nào tốt hơn?

+2

Âm thanh như bạn THỰC SỰ muốn sử dụng RVM và đá quý. Bất kỳ lý do cụ thể nào bạn chọn KHÔNG sử dụng công cụ giải quyết vấn đề của bạn một cách thanh lịch nhất? –

+4

Tôi không cam kết với bất kỳ công cụ cụ thể nào (và tôi hoàn toàn không muốn tham gia vào cuộc thảo luận "RVM vs rbenv"). Tôi quen thuộc hơn với RVM và tôi hiểu một quy trình làm việc để sử dụng nó. Tôi muốn hiểu quy trình làm việc tương đương cho rbenv, nếu không có gì khác chỉ để trôi chảy với nhiều công cụ khác nhau. –

+1

Bạn nói trang web của Bundler không giải thích cách "cô lập một dự án từ một dự án khác". Nếu "cô lập" có nghĩa là mỗi dự án có một bản sao riêng biệt của cùng một phiên bản và đá quý giống nhau (ví dụ: rack-1.4.0), Bundler không làm điều đó. Nó duy trì một bản sao của mỗi viên đá quý trên đĩa - và bất kỳ ứng dụng nào cần đá quý và phiên bản đó có thể sử dụng nó mà không can thiệp vào các ứng dụng khác.Nó giống như chạy 2 trường hợp 'bash'; bạn không có nhiều bản sao của 'bash' trên đĩa, nhưng nhiều bản sao trong bộ nhớ. Gemsets cho phép bạn có nhiều bản sao trên đĩa (có thể dễ dàng hơn để xóa khi không còn cần thiết) – Kelvin

Trả lời

12

Giả sử bạn có đường ray 3.1.0 được cài đặt, nhưng bạn muốn tạo dự án mới bằng cách sử dụng đường ray 3.2.13 chưa được cài đặt.

Giả sử bạn muốn dự án mới ở trong số ~/projects/Project2.

gem install rails -v 3.2.13 
cd ~/projects 
rails _3.2.13_ new Project2 

Điều này sẽ tạo ra Gemfile cho bạn, bị khóa vào phiên bản đường ray bạn đã chỉ định trên dòng lệnh.

Tôi cố tình bỏ qua ý tưởng giữ một bản sao riêng biệt của đá quý cho dự án mới, bởi vì điều đó đi ngược lại triết lý Bundler, đó là để có tất cả đá quý được cài đặt ở một nơi. Khi bạn chạy đường ray, Bundler sẽ tự động chọn đúng các phiên bản đá quý từ vị trí trung tâm đó. Điều đó có nghĩa là một dự án có thể chia sẻ đá quý thay vì cài đặt một bản sao mới cho chính nó. (Lưu ý, tuy nhiên mỗi phiên bản của ruby ​​bạn cài đặt sẽ có đá quý riêng của nó. Đây là một điều tốt bởi vì phần mở rộng bản địa có thể sẽ không hoạt động trên các phiên bản ruby.)

Bạn cần phải ý thức hơn một chút, bởi vì hầu hết các lệnh, như rake, sẽ tải phiên bản mới nhất của rake mà bạn đã cài đặt. Bạn sẽ cần chạy bundle exec rake ... để đảm bảo phiên bản chính xác được tải. Thông thường, tôi sẽ chạy bundle exec cho tất cả các lệnh trừ rails. Bạn có thể tạo một bí danh để làm cho nó ngắn hơn (tôi sử dụng bex). Để tự động hóa điều này với các tệp thực thi gem, bạn có thể sử dụng rbenv-binstubs, nhưng bạn vẫn phải biết rằng chạy các tệp thực thi không phải đá quý như rubyirb sẽ không tự động sử dụng Gemfile.

Sidenote: rails new sẽ chạy bundle install, sẽ kiểm tra phiên bản mới nhất của phụ thuộc. Nếu bạn muốn bundler cố gắng sử dụng đá quý hiện được cài đặt đáp ứng các yêu cầu phụ thuộc, bạn có thể bỏ qua bundle install với rails new --skip-bundle, sau đó chạy bundle check trong thư mục ứng dụng.

Sidenote 2: giả sử bạn muốn sử dụng phiên bản ruby ​​cho Project2 (ví dụ: 2.1.8) khác với phiên bản mặc định (ví dụ: 2.3.0). Trong trường hợp đó, chạy gem install như được chỉ định ở trên sẽ cài đặt các đá quý dưới 2.3.0, đó là một sự lãng phí thời gian bởi vì bạn sẽ cần phải cài đặt các đá quý một lần nữa dưới 2.1.8. Để giải quyết vấn đề đó, bạn có thể buộc các lệnh để sử dụng phiên bản ưa thích qua biến môi trường:

RBENV_VERSION=2.1.8 gem install rails -v 3.2.13 
cd ~/projects 
RBENV_VERSION=2.1.8 rails _3.2.13_ new Project2 
echo 2.1.8 > Project2/.ruby-version 

Bạn thể sử dụng rbenv shell để đặt biến, nhưng tôi chỉ khuyên rằng nếu bạn không muốn để rbenv tự động chuyển đổi dựa trên các tệp .ruby-version trong suốt thời gian của vỏ đó. Rất dễ quên rằng bạn có tập hợp biến và khi bạn chuyển sang một dự án khác, nó sẽ không sử dụng phiên bản bạn mong đợi.

+0

re: Sidenote 2 : Tôi nghĩ tôi muốn quên tên biến và phải tra cứu nó. Không xứng đáng với thời gian. Tốt hơn để mở một cửa sổ mới chỉ cho một phiên 'rbenv shell' nhanh chóng, đóng ngay sau đó. Cá nhân, điều đó sẽ dễ dàng hơn cho tôi để nhớ. YMMV. Hơn nữa, nếu bạn sử dụng 'bundle exec' cho các lệnh _all_, _including_' rails', Bundler sẽ bắt bạn nếu bạn quên rằng bạn đã chạy 'rbenv shell' và đi vào một thư mục dự án khác. –

+0

Lý do cơ bản của bạn cho việc không bắt đầu Rails với Bundler. (re: "Thông thường, tôi sẽ chạy gói exec cho tất cả các lệnh ngoại trừ các đường ray") –

+0

n.b. một số bí danh tôi bị nghiện: bí danh được = 'bó exec'; bí danh brs = 'be rails server'; bí danh brc = 'be rails console'; –

42

Hầu hết mọi người giải quyết vấn đề này bằng cách cài đặt đá quý ray trước tiên qua gem install rails. Nếu bạn từ chối làm điều đó vì một lý do nào đó, bạn có thể chọn không tham gia gói tự động mà Rails cố gắng thực hiện cho bạn. Điều này sẽ làm việc hoàn toàn bất kể hệ thống quản lý ruby ​​của bạn.

Khi được nhắc, hãy nhập "y" để thay thế Gemfile bằng Rails mặc định một (hoặc không, như bạn muốn). Sau đó, khi hoàn thành:

bundle install 

Bạn đã hoàn tất và bạn đã cài đặt ứng dụng đường ray mới với phiên bản bạn chọn mà không cần cài đặt đá quý vào đá rubygems.

+3

Không liên quan đến giải pháp này, nhưng không bao giờ chỉnh sửa tệp .bundle/config của bạn. Nếu bạn muốn cô lập các viên đá quý cho một dự án, sử dụng 'bundle install --path vendor/bundle'. – indirect

+0

Cảm ơn, gián tiếp! Bạn có thể vui lòng xây dựng trên bình luận của bạn? Có gì sai với phương pháp ~/.bundle/config? Tại sao tốt hơn để sử dụng --path? –

+0

Và trong khi chúng ta đang ở trong chủ đề của ~/.bundle/config, dấu ba chấm làm gì? –

8

Có một bài đăng gần đây về chính xác chủ đề của gemets/bundler tại đây http://rakeroutes.com/blog/how-to-use-bundler-instead-of-rvm-gemsets/ Nền tảng tốt mà bạn có thể áp dụng cho thiết lập rbenv của mình.

+0

Rất tốt. Nếu tôi biết điều đó, tôi sẽ không phải xuất bản [mỏ] (http://www.relativkreativ.at/articles/managing-multiple-rails-versions-with-rbenv) :-) –

Các vấn đề liên quan