forked from rvm/rvm
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial Ruby API, written by Darcy!!!
- Loading branch information
1 parent
0d2e294
commit 567ef6b
Showing
27 changed files
with
1,539 additions
and
439 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,156 @@ | ||
Dir.glob("#{File.expand_path(File.dirname(__FILE__))}/rvm/*.rb").each { |file| require file } | ||
# == Ruby Version Manager - Ruby API | ||
# | ||
# Provides a wrapper around the command line api implemented as part of the api. | ||
# If you're not familiar with rvm, please read http://rvm.beginrescueend.com/ | ||
# first. | ||
# | ||
# == Usage | ||
# | ||
# When using the rvm ruby api, you gain access to most of the commands, including the set | ||
# functionality. As a side node, the RVM module provides access to most of the api | ||
# both via direct api wrappers (of the form <tt><tool>_<action></tt> - e.g. +alias_create+, | ||
# +gemset_use+ and +wrapper+). | ||
# | ||
# == The Environment Model | ||
# | ||
# The RVM ruby api is implemented using an environment model. Each environment maps directly | ||
# to some ruby string interpretable by rvm (e.g. +ree+, +ruby-1.8.7-p174+, +system+, +rbx@rails+ | ||
# and so on) and is considered a sandboxed environment (for commands like use etc) in which you | ||
# can deal with rvm. it's worth noting that a single environment can have multiple environment | ||
# instances and for the most part creating of these instances is best handled by the RVM.environment | ||
# and RVM.environments methods. | ||
# | ||
# Each Environment (and instance of RVM::Environment) provides access to the rvm ruby api (in some | ||
# cases, the api may not directly be related to the current ruby - but for simplicity / consistency | ||
# purposes, they are still implemented as methods of RVM::Environment). | ||
# | ||
# When you perform an action with side effects (e.g. RVM::Environment#gemset_use or RVM::Environment#use) | ||
# this will mutate the ruby string of the given environment (hence, an environment is considered mutable). | ||
# | ||
# Lastly, for the actual command line work, RVM::Environment works with an instance of RVM::Shell::AbstractWrapper. | ||
# This performs logic (such as correctly escaping strings, calling the environment and such) in a way that | ||
# is both reusable and simplified. | ||
# | ||
# By default, method_missing is used on the RVM module to proxy method calls to RVM.current (itself | ||
# calling RVM::Environment.current), meaning things like RVM.gemset_name, RVM.alias_create and the like | ||
# work. This is considered the 'global' instance and should be avoided unless needed directly. | ||
# | ||
# RVM::Environment.current will first attempt to use the current ruby string (determined by | ||
# +ENV['GEM_HOME']+ but will fall back to using the rubies load path if that isn't available). | ||
# | ||
# In many cases, (e.g. +alias+, +list+ and the like) there is a more ruby-like wrapper class, | ||
# typically available via <tt>RVM::Environment#<action></tt>. | ||
# | ||
# == Side Notes | ||
# | ||
# In the cases this api differs, see the RVM::Environment class for more information. | ||
# | ||
# You can check the name of a given environment in two ways - RVM::Environment#environment_name | ||
# for the short version / the version set by RVM::Environment#use, RVM::Environment#gemset_use | ||
# or RVM.environment. If you wish to get the full, expanded string (which has things such as | ||
# the actual version of the selected ruby), you instead with to use RVM::Environment#expanded_name. | ||
# | ||
# Lastly, If you do need to pass environment variables to a specific environment, please use | ||
# RVM::Environment.new, versus RVM.environment | ||
# | ||
module RVM | ||
require 'rvm/errors' | ||
|
||
autoload :Shell, 'rvm/shell' | ||
autoload :Environment, 'rvm/environment' | ||
autoload :Version, 'rvm/version' | ||
|
||
class << self | ||
|
||
# Returns the current global environment. | ||
def current | ||
Environment.current | ||
end | ||
|
||
# Reset the current global environment to the default / what it was | ||
# when the process first started. | ||
def reset_current! | ||
Environment.reset_current! | ||
end | ||
|
||
# Returns an array of multiple environments. If given | ||
# a block, will yield each time with the given environment. | ||
# | ||
# RVM.environments("ree@rails3,rbx@rails3") do |env| | ||
# puts "Full environment: #{env.expanded_name}" | ||
# end | ||
# | ||
# Alternatively, you can use the more ruby-like fashion: | ||
# | ||
# RVM.environments("ree@rails3", "rbx@rails3") do |env| | ||
# puts "Full environment: #{env.expanded_name}" | ||
# end | ||
# | ||
def environments(*names, &blk) | ||
# Normalize the names before using them on for the environment. | ||
names.flatten.join(",").split(",").uniq.map do |n| | ||
environment(n, &blk) | ||
end | ||
end | ||
|
||
# Returns the environment with the given name. | ||
# If passed a block, will yield with that as the single argument. | ||
# | ||
# RVM.environment("ree@rails3") do |env| | ||
# puts "Gemset is #{env.gemset.name}" | ||
# end | ||
# | ||
def environment(name) | ||
# TODO: Maintain an Environment cache. | ||
# The cache needs to track changes via use etc though. | ||
env = Environment.new(name) | ||
yield env if block_given? | ||
env | ||
end | ||
|
||
# Merges items into the default config, essentially | ||
# setting environment variables passed to child processes: | ||
# | ||
# RVM.merge_config!({ | ||
# :some_shell_variable => "me", | ||
# }) | ||
# | ||
def merge_config!(config = {}) | ||
Environment.merge_config!(config) | ||
end | ||
|
||
# Returns the current 'best guess' value for rvm_path. | ||
def path | ||
Environment.rvm_path | ||
end | ||
|
||
# Shortcut to set rvm_path. Will set it on all new instances | ||
# but wont affect currently running environments. | ||
def path=(value) | ||
Environment.rvm_path = value | ||
end | ||
|
||
private | ||
|
||
def cache_method_call(name) | ||
class_eval <<-END, __FILE__, __LINE__ | ||
def #{name}(*args, &blk) | ||
current.__send__(:#{name}, *args, &blk) | ||
end | ||
END | ||
end | ||
|
||
# Proxies methods to the current environment, creating a | ||
# method before dispatching to speed up future calls. | ||
def method_missing(name, *args, &blk) | ||
if current.respond_to?(name) | ||
cache_method_call name | ||
current.__send__ name, *args, &blk | ||
else | ||
super | ||
end | ||
end | ||
|
||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
require 'forwardable' | ||
|
||
module RVM | ||
# Implements the actual wrapper around the api. For more information | ||
# about this design, see the RVM module. | ||
class Environment | ||
extend Forwardable | ||
|
||
%w(configuration utility alias list gemset rubies cleanup sets env).each do |key| | ||
require File.join("rvm", "environment", key) | ||
end | ||
|
||
# The default config has rvm_silence_logging so that log doesn't print anything to stdout. | ||
merge_config! :rvm_silence_logging => 1 | ||
|
||
attr_reader :environment_name, :shell_wrapper | ||
|
||
# Creates a new environment with the given name and optionally | ||
# a set of extra environment variables to be set on load. | ||
def initialize(environment_name = "default", options = {}) | ||
merge_config! options | ||
@environment_name = environment_name | ||
@shell_wrapper = Shell.default_wrapper.new | ||
@shell_wrapper.setup do |s| | ||
source_rvm_environment | ||
use_rvm_environment | ||
end | ||
end | ||
|
||
def inspect | ||
"#<#{self.class.name} environment_name=#{@environment_name.inspect}>" | ||
end | ||
|
||
# Returns the expanded name, using the same method as used by the rvm command line. | ||
def expanded_name | ||
@expanded_name ||= run(:__rvm_environment_identifier).stdout.strip | ||
end | ||
|
||
# Actually define methods to interact with the shell wrapper. | ||
def_delegators :@shell_wrapper, :run, :run_silently, :run_command_without_output, | ||
:run_command, :[], :escape_argument | ||
|
||
protected | ||
|
||
# Automatically load rvm config from the multiple sources. | ||
def source_rvm_environment | ||
rvm_path = config_value_for(:rvm_path, File.expand_path("~/.rvm"), false) | ||
actual_config = defined_config.merge('rvm_path' => rvm_path) | ||
config = [] | ||
actual_config.each_pair do |k, v| | ||
config << "#{k}=#{escape_argument(v.to_s)}" | ||
end | ||
run_silently :export, config.join(" ") | ||
run_silently :source, File.join(rvm_path, "scripts", "rvm") | ||
end | ||
|
||
def use_rvm_environment | ||
rvm :use, @environment_name, :silent => true | ||
end | ||
|
||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
module RVM | ||
class Environment | ||
|
||
# Returns a hash of aliases. | ||
def alias_list | ||
lines = normalize_array(rvm(:alias, :list).stdout) | ||
lines.inject({}) do |acc, current| | ||
alias_name, ruby_string = current.to_s.split(" => ") | ||
unless alias_name.empty? || ruby_string.empty? | ||
acc[alias_name] = ruby_string | ||
end | ||
acc | ||
end | ||
end | ||
|
||
# Shows the full ruby string that a given alias points to. | ||
def alias_show(name) | ||
normalize rvm(:alias, :show, name.to_s).stdout | ||
end | ||
|
||
# Deletes an alias and returns the exit status. | ||
def alias_delete(name) | ||
rvm(:alias, :delete, name.to_s).successful? | ||
end | ||
|
||
# Creates an alias with the given name. | ||
def alias_create(name, ruby_string) | ||
rvm(:alias, :create, name.to_s, ruby_string.to_s).successful? | ||
end | ||
|
||
# Returns an aliases proxy which can be used in a more Ruby-like manner. | ||
def aliases | ||
@aliases ||= AliasWrapper.new(self) | ||
end | ||
|
||
# Provides a Ruby-like wrapper to the alias functionality. | ||
class AliasWrapper | ||
|
||
def initialize(parent) | ||
@parent = parent | ||
end | ||
|
||
# Shows the value of a given alias. | ||
def show(name) | ||
@parent.alias_show name | ||
end | ||
alias [] show | ||
|
||
# Deletes the given alias. | ||
def delete(name) | ||
@parent.alias_delete name | ||
end | ||
|
||
# Creates an alias with a given name and ruby string. | ||
def create(name, ruby_string) | ||
@parent.alias_create name, ruby_string | ||
end | ||
alias []= create | ||
|
||
# Returns a hash of all aliases. | ||
def list | ||
@parent.alias_list | ||
end | ||
alias all list | ||
|
||
end | ||
|
||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
module RVM | ||
class Environment | ||
|
||
# Batch define common operations. | ||
%w(all archives repos sources logs).each do |cleanup_type| | ||
define_method(:"cleanup_#{cleanup_type}") do | ||
rvm(:cleanup, cleanup_type).successful? | ||
end | ||
end | ||
|
||
# Returns the ruby-like interface defined by CleanupWrapper | ||
def cleanup | ||
@cleanup_wrapper ||= CleanupWrapper.new(self) | ||
end | ||
|
||
# Implements a Ruby-like interface to cleanup, making it nicer to deal with. | ||
class CleanupWrapper | ||
|
||
def initialize(parent) | ||
@parent = parent | ||
end | ||
|
||
# Cleans up archives, repos, sources and logs | ||
def all | ||
@parent.cleanup_all | ||
end | ||
alias everything all | ||
|
||
# Cleans up everything in the archives folder | ||
def archives | ||
@parent.cleanup_archives | ||
end | ||
|
||
# Cleans up everything in the repos path | ||
def repos | ||
@parent.cleanup_repos | ||
end | ||
alias repositories repos | ||
|
||
# Cleans up everything in the source folder | ||
def sources | ||
@parent.cleanup_sources | ||
end | ||
alias src sources | ||
|
||
# Cleans up all of the logs | ||
def logs | ||
@parent.cleanup_logs | ||
end | ||
|
||
end | ||
|
||
end | ||
end |
Oops, something went wrong.