Untitled - tombo.in
Transcription
Untitled - tombo.in
rvm 1. rvm 1.1. HACKING.md # How to hack on RVM ## Fetch and try test suite on your rvm installation Note that the [`vboxtest`](docs/vm_tests.md) approach is now outdated. It's better to use the [`rvm-test`](https://github.com/wayneeseguin/rvm-test/) test suite which lives in a separate git submodule. (It's separate in order to allow reuse when hacking on rvm2). $ git submodule init $ git submodule update # Register the rvm-test submodule in .git/config # Check out the rvm-test submodule Now read [`rvm-test`'s README.md](https://github.com/wayneeseguin/rvm-test/blob/master/README.md) and follow those instructions to make sure you can successfully run the tests (you will need rvm already installed). ## Set up test installation of rvm You need a test rvm install to run the test suite against: $ $ $ $ $ git clone https://github.com/wayneeseguin/rvm export rvm_path=~/path/to/rvm/test/install export rvm_bin_path=$rvm_path/bin cd rvm ./install # or your own github fork # choose a path here This will create a test installation of rvm in `~/path/to/rvm/test/install`, and as long as `$rvm_path` points to it, this will be used when running the tests. This means you can safely break the test installation without risking breaking your main rvm installation. If you want to do manual testing on the CLI against this test installation, you also need to do: $ rvm reload ## Hacking RVM via TDD (Test-Driven Development) First write a test for the behaviour you expect. For details on how to write new tests, see [`rvm-test`'s README.md](https://github.com/wayneeseguin/rvm-test/blob/master/README.md). Then run the test: $ tf --text rvm-test/fast/foo_comment_test.sh It should fail. Now repeat the following steps until the test passes: 1. hack the changes in your rvm src tree 2. run `./install` 3. re-run the test (you can also manually test via rvm commands on the CLI) Now `git commit`, `git push` to your github fork, then issue a pull request, and if it is accepted then your place in hacker heaven is secured. ## Getting help If you get stuck, you should ask on `#rvm-test` or `#rvm` on Freenode. 1.2. install scripts/install 1.3. README.txt README 1.4. .gitmodules [submodule "rvm-test"] path = rvm-test url = git://github.com/wayneeseguin/rvm-test.git 1.5. LICENCE Copyright (c) 2009-2011 Wayne E. Seguin Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 1.6. README.rdoc README 1.7. .gems travis-lint 1.8. VERSION 1.14.10 1.9. .travis.yml language: ruby rvm: - 1.9.3 install: gem install tf before_script: - rvm alias delete default - hash -r - ./install - rvm-smile - git submodule init - git submodule update script: tf --text rvm-test/fast/* notifications: irc: channels: - "irc.freenode.org#rvm-test" - "irc.freenode.org#rvm" email: recipients: - mpapis@gmail.com - me@deryldoucette.com on_failure: change 1.10. History.txt = RVM History, thanks be to Git. == Release 1.7.1 * Remove playful jab. * Merge pull request #369 from thinkerbot/vbox-test * added vm test scaffold * Merge pull request #368 from benmoss/patch-1 * Fix some typos * I have to stop doing so many things at once. ... Nah... who am I fooling? :) == Release 1.7.1 * Merge branch 'master' of git.overnothing.com:rvm * Rake is now stable at 0.9.2, good default there. * Perhaps this will help solidus-river. * Merge pull request #366 from deryldoucette/master * Made NOTE: part green as well just to ensure people see it. * Fixed and color coded per-project rvmrc example. * Added information to 'rvm notes' about the >= 1.7.0 per-project .rvmrc toggle. * Account for Lion default clang in packages also. * Bugfix for zsh, array indexing differences are always good for a certain kind of chuckle. * Turns out we already had a History.txt file :) * Merge pull request #365 from burningTyger/rdoc * rdoc instead of markdown * space cadet. * The redundency bothered me. * On long reflection, 90% of the issues I have seen are to do with rvm_path setting. If you are root, /usr/local/rvm If you are a user, $HOME/.rvm == Release 1.7.0 * Since this is not read anyway, I might as well have some fun with it! * Default rvm_project_rvmrc to off, set rvm_project_rvmrc=1 in ~/.rvmrc to enable. Oh wow, you mean you could toggle it??? Yes. Always could. Wow I should have asked!! Yes... yes you should have... Amazing how much you learn by simply asking a question... * Added missing example. * Merge branch 'master' of github.com:wayneeseguin/rvm * RVM History, thanks be to Git. * Merge pull request #364 from jfredett/master * fix typo (doubled 'bison') in arch bootstrap script and in script/notes * Merge pull request #363 from aghecht/master * Adding missing shell functions * Merge pull request #362 from ognevsky/fix-typo-in-implode * Fixed typo in implode * Correcting install messages. * fix local arrays in trusting * fix trusting on zsh * Merge pull request #361 from zaadjis/master * Fixed untrusting rvmrcs. * Copy paste can get you into trouble sometimes ;) * Merge branch 'master' of github.com:wayneeseguin/rvm * Swiped md5 code from BDSM * Merge pull request #359 from agibralter/master * Allow hooks directory or hooks to be symlinked. * Merge pull request #358 from chrismealy/master * Added automake (to get aclocal) to dependencies for Ubuntu. * Merge pull request #357 from tabletcorry/master * Merge branch 'master' of github.com:wayneeseguin/rvm * prevent duplicate suffixing * cleanup. * Cleanly return in case of not in a git repository tree. * Add a check to FQ rvm_path * Merge pull request #356 from dsedivec/master * Allow irb switches to set the prompt mode * Merge pull request #354 from lribeiro/master * Merge pull request #355 from ncreuschling/master * removed duplicate dependency from installation notes * we dont need to depend ant dist to build jruby, ant jar is enough and a lot faster * Merge pull request #353 from MagLev/MagLev-26355 * do not require double -- after --name * do not pass args before -* Merge branch 'master' of github.com:wayneeseguin/rvm * do not pass args before -* Updated to MagLev-26355 * Merge pull request #352 from meqif/master * Fixed zsh bug when glob_subst is set. * use a local for the file looping over. * Merge branch 'master' of github.com:wayneeseguin/rvm * Added popd hijack. * Merge pull request #351 from goncalossilva/master * added gcdata patch for 1.9.3-preview1 * added gcdata patch for 1.9.2-p290 * Merge branch 'master' of github.com:wayneeseguin/rvm * cleaning mri detection for other rubies * Merge pull request #349 from deryldoucette/master * remove test output * manual printf as find not allways supports it * fix detection mri rubies * Some cli cleanup. * Fixed errant help message. Was displaying 'rvm package' rather than 'rvm pkg' as it should. * flipNzBit! * Merge pull request #347 from mblair/master * so it's like the others * tyop. * Really? Homebrew? Have another... == Release 1.6.32 * Ruby 1.9.3-preview1 is now default 1.9.3 * Merge pull request #346 from amarshall/rbx-1.2.4 * Rubinius 1.2.4 * Merge branch 'master' of github.com:wayneeseguin/rvm * fix --no-tcmalloc on OSX when user provided options * Initial groundwork for "rvm group" feature, untested * Merge pull request #345 from tricknotes/master * Changed package to pkg on README * make rbx work * Merge pull request #344 from tsykoduk/master * Merge branch 'master' of github.com:wayneeseguin/rvm * fix bunzip2 error * changed package to pkg on help text to correctly reflect real command == Release 1.6.31 * git it done man, git it done. * NO Effin Comment. I am with @joedamato on this one. * Allow 1.9 in dependency check for Rubinius, requiring MRI. == Release 1.6.30 * RubyGems 1.8.6 as default, w00t!!! == Release 1.6.29 * claening * restore jruby hook code, it is already disabled by default * Merge branch 'master' of github.com:wayneeseguin/rvm * no default jruby/ng on install, persist hooks x flag on install * make 1.9.3-head working * fix reading db * Dismount. == Release 1.6.28 * "rvm refresh ..." => "rvm reinstall" as suggested by v0n * Feature: rvm refresh 1.9.2 ~ equivalent to rvm remove 1.9.2 ; rvm install 1.9.2 == Release 1.6.27 * Removed ebuilds. * Also set CC on Darwin for 1.9 Rubies, for now. * Updated ebuild for latest release. == Release 1.6.26 * export CC="/usr/bin/gcc-4.2" if darwin11 * Merge pull request #343 from telemachus/lion * Add a note/warning about gcc vs llvm on Lion * Merge branch 'master' of github.com:wayneeseguin/rvm * fix installer to not make jruby hook +x when it was -x once * No comment. * Merge branch 'master' of github.com:wayneeseguin/rvm * improved jruby support, allow to set per project options (in .rvmrc) * Merge pull request #342 from MagLev/MagLev-26231 * Updated to MagLev-26231 * update support for ubuntu * Merge pull request #341 from anl/master * Merge remote-tracking branch 'rvm/master' * Adjusted logic. * Merge pull request #340 from joshuacronemeyer/master * Merge remote branch 'upstream/master' * change fetch script to account for the fact that curl wasn't giving an error when it got a 404. case use -f switch to ensure it. * Merge pull request #339 from psanford/fix_global_rvm_path * Fix "grep: Invalid range end" messages on FreeBSD. * Fixed rvm.sh setting path for global installs. * Fix FreeBSD "pw groupadd" syntax. * Merge pull request #337 from MagLev/MagLev-26197 * Wrestling the ZSH beastiality beast. * Updated to MagLev-26197 * Fixed incorrect formatting and inconsistency. * Adjusted testing for teardown. * Merge pull request #321 from darren-fhf/master * Bugfix in rvmrc generator. * Updated ebuild for latest release. * Merge branch 'master' of github.com:wayneeseguin/rvm * fix after == Release 1.6.25 * Merge branch 'master' of github.com:wayneeseguin/rvm * fix removing jruby functions * jruby hook enabled by default * note about after_use hooks * fix hooks installation * Let us not forget about zsh :) * after_use hooks must be executable to be turned on now. * Merge branch 'master' of github.com:wayneeseguin/rvm * Added rubygems diretory. * Fixing unsets. * Merge pull request #336 from jzacsh/master * Merge branches 'master' and 'master' of git://github.com/wayneeseguin/rvm * Fixing bug introduced in 203257a by pull request #333, case-modification is a bash4ism [1]. * More .gitignore files. * pkg * pkg!!! fetch should fail in that * hooksssssssssssssssss * Minor tweaking of awesome work by mpapis. * Merge pull request #335 from mpapis/ng * fix after_use hooks, add jruby --ngserver support * Good cop. Bad cop. * Why... whatever could I be up to? * Merge branch 'master' of github.com:wayneeseguin/rvm * package :) * Merge branch 'master' of github.com:wayneeseguin/rvm * pkg :) * Merge pull request #333 from jzacsh/master * Missed one. * Bombs away!!! * pull #333: implified logic for user simply hitting [enter] key. * using case in place of if for possible "yes" or "no" in user-response. * taking advantage of the printf that was already there; a whee-bit nicer. * making sure that the while condition actually make sense. utilizing boolean-ish~ness with bash arithmetic, ease of reasdability. lower-casing response immediately. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Merge pull request #334 from t-nagamatsu/patch-1 * Updated ebuild for latest release. * Hook code cleanup. * Updated ebuild for latest release. == Release 1.6.24 * Merge pull request #331 from jrep/master * Always store project .rvmrc trust keyed by the full, only slightly munged, path Prune old-style md5-keyed entries during install Mention all this in notes * changed each option sequence. unexpected error won't occur to run 'package install zlib' on Mac OS X 10.6. "ERROR: Error running '/*/make install', please read /*/make.install.log" * Merge pull request #330 from griff/master * simplified prompt for rvmrc trust, infinate loop not a threat, as user can interrupt script at any time. * updated copy to no longer reference `less` pager, as it seems cat is used now for security purposes. * simplified checking of params. * yoda~ish logic from [not, else] to [if, then] * Updated ebuild for latest release. == Release 1.6.23 * Merge branch 'master' of github.com:wayneeseguin/rvm * Ruby 1.9.2 p290 is now default. * Recall the checksum of a trusted project .rvmrc. * Added code to set rvm_user_install_flag in scripts/initialize * Merge pull request #328 from gabemc/master * Merge pull request #329 from biow0lf/master * Merge branch 'master' of github.com:wayneeseguin/rvm * rvmsudo: fix vairable values with spaces * Add ruby-1.9.3-head * Making md5sum the default executable, to fix an issue on Cygwin, which doesn't have a correctly formatted MACHTYPE. * Merge pull request #327 from nibrahim/master * Escape grep * update instructions for reload * fix variable values containing spaces * yaml v0.1.4 * Merge branch 'master' of github.com:wayneeseguin/rvm * Installer adjustment. * Merge pull request #326 from arunagw/jruby163_test * Tests added for JRuby-1.6.3 * Merge pull request #325 from terabyte/master * Fixed error message when you 'gemset create' before 'use ruby'. * Updated ebuild for latest release. == Release 1.6.22 * JRuby 1.6.3 * Merge pull request #323 from andrew/master * Merge pull request #324 from mhorbul/master * use TMPDIR value or /tmp by default. This will allow to update rvm when /tmp is mounted with noexec flag * Updated rails bootstrap script to install rails 3.0.9 * Merge branch 'master' of github.com:wayneeseguin/rvm * inform user about reload\! * reworked rvmsudo: forward all rvm variables (and possibly more) * fix loading/reloading rvm * Merge pull request #322 from MagLev/maglev-newMac * Handle pre-installed gems for MagLev * add libxslt for yum: needed in CentOS 5.6 * Merge branch 'master' of github.com:wayneeseguin/rvm * fix capistrano :system for rvm 1.6.21 * Updated ebuild for latest release. == Release 1.6.21 * Merge pull request #320 from koraktor/ruby-1.8.7-p352 * Merge branch 'master' of github.com:wayneeseguin/rvm * make rvm ruby lib work properly with 1.9.2 * Ruby 1.8.7 has been updated to patch level 352 * Merge pull request #319 from kbrock/master * rvm wrapper now properly symlinks to a command with an absolute path * fix zsh installation (process env persistance) * always export rvm_path (sourced from .rvmrc) * silence pushd/popd * Merge pull request #318 from danhealy/master * rvm_prefix does not have a trailing slash * Merge pull request #317 from dplummer/patch-1 * Fix skipping extract step for REE * fix root 'user' installation * Merge pull request #316 from tylerhunt/patch-1 * Fixed a typo in the gemset_empty() warning. * Merge pull request #314 from griff/master * Merge branch 'master' of https://github.com/wayneeseguin/rvm * Restructured how the - separator gets inserted in rvm-prompt to remove the need for sed editing at the end * fix defaults to root * fix rvm self contained feature * Merge pull request #313 from griff/master * Found a few log calls that was missed when logging was pulled internal * Merge pull request #312 from cobracmder/master * made minor grammar changes * Merge pull request #311 from cobracmder/patch-1 * Minor grammar changes * Merge pull request #310 from MagLev/MagLev-26063 * Updated to MagLev-26063 * Merge pull request #307 from threedaymonk/master * Merge pull request #309 from MagLev/maglev-newMac * Merge pull request #308 from justinko/master * Fix problem causing selector to download/compile curl * Merge pull request #306 from MagLev/maglev-newMac * spellcheck * Correct spelling of possessive its * Fix up GemStone version for "rvm install maglev-head" * rvm_gemstone_version * Merge pull request #305 from MagLev/maglev-newMac * Fix bad location for uncompressed GemStone directory * Array! Yay! * Merge pull request #304 from iangreenleaf/master * Missed a spot! Spot! There you are lil guy!!! * Anyone else hear circus musik? * Cleanup, aisle MagLev. * scripts/base in maglev. * Only add users to group if thy aren't members * Check users against passwd file * Merge pull request #303 from MagLev/maglev-newMac * Change so RVM doesn't override preinstalled RubyGems for MagLev * Merge branch 'master' of github.com:wayneeseguin/rvm * bashrc * Merge pull request #302 from szTheory/master * fixed issue where Result#initialize would blow up if status was false, giving (NoMethodError: undefined method '[]' for false:FalseClass) on result.rb:14 * Merge branch 'master' of github.com:wayneeseguin/rvm * Try exporting rvm_path. * Merge pull request #301 from Spaceghost/master * Merge pull request #300 from MagLev/maglev-newMac * Made rvm always create a hooks directory. * Handled case where MagLev arch was x86-64 but file is i386 * Merge pull request #298 from mpapis/master * Merge pull request #299 from MagLev/MagLev-25987 * Updated to MagLev-25987 * fix macport manage script * Merge pull request #296 from buysse/improve_rvmsudo * Merge pull request #295 from geemus/master * Merge pull request #294 from gstark/fix_logging_output_tput_styling * Merge pull request #293 from HeSYINUvSBZfxqA/master * Merge pull request #297 from remear/master * Added strings option to gemset listings. rvm gemset list strings * Added support for sudo flags (such as -H) to the rvmsudo script * [help] add use docs * [help] add uninstall docs * [help] add remove docs * Removed the unset for rbxopt, allow it for all rbx installs. * Detect interactive shell by looking at STDOUT for colorized logging. * quote --no-same-owner option with tar command for ree/maglev * 2.0.0pre @tmorini :) * Merge pull request #292 from mblair/master * typo fix * Use RVM path. * Updated ebuild for latest release. == Release 1.6.20 * Updated ebuild for latest release. * Truncate logs so that logs reflect last run. * A tweaking we will go, a tweaking we will go... * rvm_install_args * rbx is not compatible with rbx :-p * For rbx allow args to be passed through directly to configure. * Account for name case. * rbx counts too ;) * rvm install rbx-2.0.0pre will work tomorrow ;) * Updated ebuild for latest release. == Release 1.6.19 * Bugfix, we have ruby at this point, might as well use it to generate a yaml output of the env ;). * Try that rboyd... * Move --no-same-owner inside. * Put back an empty file. * Merge pull request #291 from indirect/master * Only track the latest of each point release in known. * Stop forcibly setting BUNDLE_GEMFILE for now, because it stays set forever. * Remove bundle shell function for now * Added missing sources. * Merge branch 'master' of github.com:wayneeseguin/rvm * Cleaning up manage script by breaking it out into files. * Merge pull request #290 from swhitt/master * Running "bundle" by itself is the same thing as running "bundle install". * Merge branch 'master' of github.com:wayneeseguin/rvm * Bugfix in installer thanks to yonahw. * Merge pull request #289 from mpapis/master * fix BUNDLE-INSTALL(1) BUNDLE-INSTALL(1) * Merge branch 'master' of github.com:wayneeseguin/rvm * ignore RybMine configuration * handle BUNDLE_GEMFILE, added default for projects that do not provide it * Merge pull request #288 from shtirlic/patch-1 * Fix for zsh. * ensure not finding the function. * Altered rvm loading. * better handling bundler, do not generatecomments for PATH * do not create separate bin dir for bundler, let it overwrite gem * "life" is the better word than "work" ;) * Some manage cleanup. * Merge! * stars. * Acting on comment suggestion from githuh. * Merge pull request #287 from mpapis/master * fix bundle binstubs * Merge pull request #286 from mpapis/master * improved bundle commnad * Helps to actually git add the file. * Account for bundler in rvm itself now. * Merge pull request #284 from docwhat/master * Merge pull request #285 from mattalbright/master * This fixes the bug where system-installed RVM on Mac doesn't properly add the users to the rvm group. To properly add Mac users to the rvm group, list all users that are in the "staff" group, which seems to mean can login. * Typo in example rvmrc * Merge pull request #283 from ncreuschling/master * Escape! Escape! * Merge branch 'master' of github.com:wayneeseguin/rvm * bump version defaults in bootstrap script. * fixed typo * Merge pull request #282 from MagLev/MagLev-25913 * Updated ebuild for latest release. == Release 1.6.18 * Added lines for bundler users to generated rvmrc (rvm --create --rvmrc use X@Y) * Added a comment. * Updated ebuild for latest release. == Release 1.6.17 * More robust generated rvmrc files, better error handling. * Merge branch 'master' of github.com:wayneeseguin/rvm * The proper thing to do is to use autoreconf, not autoconf. Learning autotools proper usage is highly recommended. * Updated to MagLev-25913 * Merge pull request #281 from nwjsmith/master * Fix typo * Merge pull request #280 from mpapis/master * Merge branch 'master' of github.com:wayneeseguin/rvm * memory note for Rubinius * added instructions for opensuse * Merge pull request #279 from ajburton/md5_fix * fixes test syntax * vbatts is correct. * Properly denote the default version of JRuby. * Merge branch 'master' of github.com:wayneeseguin/rvm * Updated ebuild for latest release. == Release 1.6.16 * Source packages at the top. * Such tender love went into the making of this feature :) * Merge pull request #277 from arunagw/jruby_tests * Tests added for jruby-1.6.2 #jruby * Minor cleaning. * Do not switch rubygems on JRuby. * Merge branch 'master' of github.com:wayneeseguin/rvm * JRuby 1.6.2, w00t! * Updated ebuild for latest release. == Release 1.6.15 * Merge pull request #276 from ilikepi/fix_missing_then * Add missing "then" to scripts/rubygems * Added DESTDIR * rubygems script cleanup. * Updated ebuild for latest release. == Release 1.6.14 * More installer fixes. * Merge branch 'master' of github.com:wayneeseguin/rvm * I see stars! * Merge pull request #275 from mpapis/master * fix compilation with openssl 1.8.6 * I never thought that I would be doing this :) * Updated ebuild for latest release. == Release 1.6.13 * WHY was that not executable??? * More progress cleaning up installer. * Look, the cure for stupidity consists of space! * Gotcha you lil buggar! * More installer refactorings, trying to get to the bottom of that annoying issue. * Some cleanup of the rvm-installer. * Only append to profile file if it exists. * Array start bugfix and gemset script cleanup. * * * * * * Somehow it managed to elude me. Ensure that scripts that should be executable are. Bugfix? Bugfix? If not connected to an interactive session, return. Updated ebuild for latest release. == Release 1.6.12 * Merge branch 'master' of github.com:wayneeseguin/rvm * Updated ebuild for latest release. == Release 1.6.11 * Merge pull request #271 from adevadeh/patch-1 * Merge pull request #272 from yonahw/bad_taste_in_branch_naming_accepted_NOT_encouraged * Merge pull request #273 from MagLev/MagLev-25876 * Merge pull request #274 from thomasjachmann/master * fixes installer bug introduced in 10.6.10 * I blame gitflow for this atrocity * split bunzip into 2 lines, the one-liner fails in RHEL4 for some reason. 2 lines works for RHEL4, RHEL5, Ubuntu, and MacOS, have not tested anything else * Updated to MagLev-25876 * Updated ebuild for latest release. * 1.6.10 * Merge branch 'master' of github.com:wayneeseguin/rvm into rbx * Bugfix: unbound variable in cli. * Merge pull request #270 from ahamid/master * add switch for explicit user install setting; helpful with root * Merge branch 'master' of github.com:wayneeseguin/rvm * More housecleaning. * Merge pull request #269 from pvande/master * Fixed postinstall note output. * More cleanup. * only call the command if it is loaded, first install should not error. * Low hanging fruit plucking. * Adjusted __rvm_18_compat_ruby to exclude rbx, since we do not want rbx to build rbx. * Always load the .rvmrc if in an interactive shell (open new tab in same dir). * Clean up some RubyGems-related duplication. * Merge pull request #268 from CraigCottingham/rvmselect * Merge branch 'master' into rvmselect * Merge branch 'rvmselect' * Add scripts/functions/developer, from https://gist.github.com/984bd56424be200532d0 * Merge pull request #267 from CraigCottingham/cleanup-bin * Fix call to match() in __rvm_remove_binaries() * Began cleaning up the installer. * Cleaned up wrapper code some. * Thank yøu bhenderson. * Updated ebuild for latest release. == Release 1.6.9 * Fixed an assinine bug thanks to stepheneb. * Properly test for interactive mode. * Removed no longer necessary code. * Updated ebuild for latest release. * The LOFL I am sick of this shit release! * Merge branch 'master' of github.com:wayneeseguin/rvm * LOFL! * Merge pull request #266 from MagLev/MagLev-25838 * Switch to antialias. * Corrected ordering. * Updated ebuild for latest release. == Release 1.6.7 * Synchronizing the code repetition blocks. * Merge branch 'master' of github.com:wayneeseguin/rvm * Level the playing field. * Merge pull request #265 from gabebw/dollar-dollar * Use cp -f and rm -f when dealing with /tmp/$$ * Updated ebuild for latest release. == Release 1.6.6 * Updated to MagLev-25838 * Only if prefix is nonempty. * Adjusted __rvm_project_rvmrc() * Merge pull request #264 from derekprior/help-updates * Works with 1.9.* as well. Added bit about 'rvm rubygems remove' from the rvm website. * Merge branch 'master' of github.com:wayneeseguin/rvm * set -fu * Merge pull request #263 from meineerde/setup_rvm_group_users-with-no-users * Fix setup_rvm_group_users for the case when there are no additional users. * Tweaked recursive copy. * Add a reset --hard HEAD on rbx build. * handle get specially. * resolution * s/aptitude/apt-get/g Many users of Debian certainly and probably other Debian-derived distros prefer 'apt-get' to 'aptitude'. For whatever reasons [Ubuntu has actually stopped shipping with 'aptitude' by default](http://www.webupd8.org/2010/06/aptitude-removed-from-ubuntu-1010.html). Without debating the technical merits of either tool, I would say this: * Merge pull request #259 from matschaffer/patch-1 * More set -u fun. * set -u should be outlawed :-p * Bugfix: scripts/functions. * Removeperpetual d call to display_osx_hint. * Adjusted rvm path setting. * Merge pull request #260 from rosenfeld/master. * Merge pull request #261 from alec-c4/master. * Added hint for OSX users * Add example for tweaking Gem options * Loading cleanup, adjusting more for zsh. * Bugfix: ZSH random declare. Adjusted rvm_user_install with _flag postfix as that is what it is. Corrected usage of rvm_user_install_flag. * Merge branch 'master' of github.com:wayneeseguin/rvm * Bugfix: do not allow missetting of rvm pretty print flag to blow up. * Merged pull request #258 from pweldon/fix_config_user_mv. * Ensure aptitude is installed. * fix logic for moving config/user -> user/db * Merge branch 'master' of github.com:wayneeseguin/rvm * --no-same-owner is back!!! :) * Merged pull request #256 from ConradIrwin/sha1-simplification. * Merged pull request #257 from utkarshkukreti/patch-1. * Add newline after the error message on running `rvm update`. * Further simplify SHA1 extraction. * Merged pull request #253 from bergalath/master. * Merged pull request #254 from pweldon/fix_user_db. * Merged pull request #255 from ConradIrwin/master. * Tidy up, and comment option setting. * Yeah... I see you too zsh... * extglobbing fun :) * Merge branch 'master' of git.overnothing.com:rvm * Ying, meet Yang. * Fix user db overrides to use $rvm_user_path/db consistently. * Updated ebuild for latest release. == Release 1.6.5 * Using `git rev-parse` instead of `git log --no-color -1` to get the last sha1 commit on current branch so we can remove some treatment. * Ubuntu sucks arse through a straw. * Merge branch 'master' of github.com:wayneeseguin/rvm * Merged pull request #251 from ConradIrwin/fix-nonomatch. * --no-same-owner thanks to ngan. * Merged pull request #252 from kaerast/master. * Return on error. * Removed duplicated flags, thnk you very much arrix. * added missing dependencies for Centos * Updated install line in readme, thanks to crankharder for pointing it out. * -o... * Correct and clarify resetting of zsh options. * Updated ebuild for latest release. == Release 1.6.4 * Wow... that was a brainfart. * Merge branch 'master' of github.com:wayneeseguin/rvm * Select if not selected. * More cleanup prompted by last pull request. * fixed my brain * We found you, you little snot * Trying to do too many things at once :/ * Added rvm_rbx_opts to example rvmrc with comments. * This part needs more thought. * More cleanup. * ... * ... * Merge branch 'master' of git.overnothing.com:rvm * Syntactical Cleanup. * Added RBXOPT to environment file recording. Cleaned up environment files and code some. * Defaut RBXOPT to -Xrbc.db and -Xagent.start, overrides by setting rvm_rbx_opt in rvmrc. * Merge branch 'add_jruby_161_to_known' of https://github.com/sferik/rvm into sferik-add_jruby_161_to_known * Missed a q. * Add JRuby 1.6.1 to the list of known rubies * Merge branch 'fix-install-errors' of https://github.com/chrislwade/rvm into chrislwade-fix-install-errors * Default to Jruby-1.6.1 * Fix typos. * Fix errors reported during install. * Updated ebuild for latest release. * People define "stable" by version numbers, so here I give them another #daft. * Added rvm-exec to binscripts installation thanks to arrix. * Removed eval from end of rvm-exec. * Stick with builtin. * Some cleanup. * Merge branch 'issues/fix-missing-escape' of https://github.com/meineerde/rvm into meineerde-issues/fix-missing-escape * Merge branch 'MagLev-25716' of https://github.com/MagLev/rvm into MagLev-MagLev-25716 * rvm-installer: fix typo in "--version latest" switch * Added rvm-exec as per suggestion by Arrix Zhou. * Updated to MagLev-25716 * Fix another typo * Fix missing escape * Slight cleanup of new function. * Feature: rvm gemset search <gem name> strings * Feature: rvm gemset search <gemname> * Updated ebuild for latest release. == Release 1.6.2 * Adjusted ps1_titlebar as recommended by @chrislwade. * Merge branch 'MagLev-25681' of https://github.com/MagLev/rvm into MagLev-MagLev-25681 * F'n Solaris. * already gone! * Bugfix: rvm_make_flags_flag * Adjusted ps1_titlebar * Updated to MagLev-25681 * Merge branch 'master' of https://github.com/skaes/rvm into skaes-master * Take rubygems to 1.6.2 until I can complete the new feature. * Fixes bug with calling shopt with ZSH * run autoconf if the configure script is older than configure.in * Updated ebuild for latest release. == Release 1.6.1 * Merge branch 'master' of https://github.com/MagLev/rvm into MagLev-master * Merge branch 'ps1_titlebar' of https://github.com/thecatwasnot/rvm into thecatwasnot-ps1_titlebar * Merge branch 'codegnome/issue-001' of https://github.com/CodeGnome/rvm into CodeGnome-codegnome/issue-001 * Merge branch 'codegnome/issue-002' of https://github.com/CodeGnome/rvm into CodeGnome-codegnome/issue-002 * Defaulting Rubygems version to 1.4.2 based on Evan Phoenix's recommendation. == Release MagLev-25665 * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Updated ebuild for latest release. == Release 1.6.0 - https only. * https AAAAARRRRRGGGGGGHHHHHHHHHHHHHHH * __rvm_ask_to_trust(): Aligned 'yes or no' prompt. * Better user messages for __rvm_ask_to_trust(). * Bumped minor version for HEAD. * Updated ebuild for latest release. == Release 1.5.4 * rvm use 1.2.3 => rbx-1.2.3 * Ensure extglob is on for r() * Updated ebuild for latest release. == Release 1.5.3 * Adding titlebar back for xterm in contrib/ps1_functions * Altered new git status ps1 feature to minimize external calls. * Merge branch 'git_status' of https://github.com/carlosgaldino/rvm into carlosgaldino-git_status * Update to MagLev-25646 * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Bugfix: adjusted printf. * Adjusted rm_rf * nn * Fixed regression in 'require' * Update to MagLev-25568. Fixes SEGV in MagLev FFI code on Linux * show git status * Removed extra escape. * Updated branching logic thanks to prompting by hiroshi. * Merge branch 'fix_branch_select_patterns' of https://github.com/hiroshi/rvm into hiroshi-fix_branch_select_patterns * Fix patterns for $(git branch) * Merge branch 'master' of https://github.com/wayneeseguin/rvm into macruby_repo_url_github * Changed macruby_repo_url to github * Merge branch 'master' of https://github.com/ashgti/rvm into ashgti-master * Bugfix: call gemset_import in import(), thanks to hedge-hog. * Update the ps1_set to escape all of the coloring parts so you can use a separator that is not a new line and not mess up your prompt. See contrib/ps1_functions for more detail. * Create and add $rvm_bin_path if necessary * Removed extra fi from removed test. * Alter calculation of user_install detection. * Go through full RVM path initialization in rvm-shell. * Merge branch 'untar-ownership' of https://github.com/meineerde/rvm into meineerde-untar-ownership * Merge branch 'cleanup_192_pre' of https://github.com/sferik/rvm into sferik-cleanup_192_pre * Remove all 1.9.2 pre-releases now that 1.9.2 is final and stable * Add -o parameter to all tar extractions to not use existing users and groups when running as root * Set $rvm_prefix to actually allow to override the target $rvm_path * Allow to actually set an install path other than /usr/local/rvm * Add missing shift to allow '--version latest' * if exec is called bypass loading libs. * Merge https://github.com/arunagw/rvm into arunagw-56b6e97 * Merge branch 'master' of https://github.com/goncalossilva/rvm into goncalossilva-master * Sanity check for the case we are not in a git branch. * Merge remote-tracking branch 'upstream/master' * Initialize the variables to make sure they are set. * Updated ruby186gc for the latest patchlevels. RVM applies patches with -p1, changed patch headings accordingly. * added the "ruby186gc" and "ruby187gc" patches * Bugfix: remove symlink if it exists. * Updated ps1_functions based on discussion with @0x44 * Fixed gems to gemset * Only chown as root. * Bugfix: if the hooks files are the same, only run once. * More replacement of 'gems" to "gemset" * Replacing gems to gemset in test/unit/gemset_test * Modified PS4 again. * Test for jruby 1.6.0. Default is jruby-1.6.0 * added working gcdata patch for mri 1.9.2-p180 * removed non-functional 1.9.3 gcdata patch * Updated PS4 to a more readable version. * s/exec/eval/:( * I am so insanely daft that I make my pet rock look smart :/ * Adjusting rvmsudo for debugging. * Bugfix: Globbing now works properly in zsh. * Bugfix: Preserve arguments to rvmsudo. * Bugfix: Keep bin path default scripts in sync. Copy instead of symlink. * Bugfix: account for multiple digits and up to three. * LOFL * Adjusted binscripts methods. * Bugfix: version detecting for macruby. * Adjust for possibility that path is nil? * Adjust cap integration for the removal of system-wide. * Updated ebuild for latest release. == Release 1.5.2 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Ensure etc_profile_file is assigned. Empty check. Missed gems, environments and wrappers. Ensure rvm path dirs exist. Explicit instead of implicit. vra tyop. Rebuild instead of migrate. Close if, silly! s/rvm_selfcontained/rvm_user_install/g More work on profiles. tyop Are we there yet? Automatic user profile setup, Yehuda might yell at me for putting this back ;) Always call setup_rvmrc Improved default rvmrc logic. Respect --path. More fine tweaking. New tactic, only load the associated rvmrc file :) Forcable AND direct! be more direct with setting rvm_path. dassinine - verb - daft and assinine Ahhh it is the token! Allow for rvm-installer x.y.z chmod +x ! Determining install path comes first. More work on the installer. Turn on extended globbing. Added new rvm-installer script which combines all functionality of the install-latest install-head and get API. Merge branch 'master' of https://github.com/nerdyc/rvm into nerdyc-master profile.d scripts must be executable. LOL! Working on better profile.d logic. Update rvm ruby selector script to support MacRuby 0.10. .sh :(, thanks bradland ! Symlink to prefix path bin, not hardcoded to /usr/local/bin Use /etc/profile.d if it exists, otherwise fall back on /etc/profile. Bugfix: I was a bit overzealous when escaping things :) Use the rubygems API as part of manage. Give the user more information during root installation. Merge branch 'master' of https://github.com/zendesk/rvm into zendesk-master Loading rvmrc fits better in install_setup. == Release 1.5.1 - rvmrc files are now respected during installs. * Respect main rvmrc files. == Release 1.5.0, anything less is UNSUPPORTED :) * Sneeky buggars! * Updated update head script. * FI fi fo fum! * Fun with function names, w00t! * So how about we actually append to the file, yes? :) * What is in a name? * Keep on drillin! * Move parse args for clarity. * More root canal work. * RVM built in installer now handles root installation. == Release 1.3.2 * MacRuby 0.10, w00t! * Fixed an insanely daft bug. == Release 1.3.1 * Fuck you system wide, fuck you. * Explicitly do not load rvm. * Determine paths separately from loading RVM. * Use printf, rvm_error has not yet been loaded yet at this point. * Lock and load. * fixing rvm get x.y.z * Merge branch 'purple-directory' of https://github.com/carlosgaldino/rvm into carlosgaldino-purple-directory * Merge branch 'master' of https://github.com/zendesk/rvm into zendesk-master * Refactored Install script, it is now much more readable and maintainable. * turn off die on error in tmp cleanup trap for shell scripts that enable set -e * Missed a spot :/ == Release 1.3.0 * Switching to a far superior rubygems download url, w00t!!! Thanks kotique! * directory is now purple * Escape as we do not mean a unicode sequence :) * Added contrib to installer. * Added ps1_functions to contrib/ * More trailing slash guards. * Account for odd trailing slashes in install script. * Remove i386 CPU_TYPE check since new macs return x86_64 Update to version 25506 * Switched from external calls to using $UID as suggested by methods. * Finishing touches for kiji interpreter thanks to initiative by Blue Box Group. * Merge branch 'master' of https://github.com/blueboxgroup/rvm into bbg * Merge branch 'master' of https://github.com/yura/rvm into yura-master * Merge branch 'master' of https://github.com/erikh/rvm into erikh-master * Completely removed rvm_interactive_flag, checking directly each time as per recommendation by e2 for zsh. * Autodetect rvm_interactive_flag every time * Found a few more places... * First flushout to add kiji. * Fix ri generation * don't need to emerge libxml since it's ruby package in gentoo and required ruby 1.8.7 to be emerged == Release 1.2.9 * JRuby 1.6.0 is now default. * Added rbx-1.2.3 * Update to MagLev-25439. Seaside works again. * Added a project specific hook check. * Bugfix: hooks :) * Default to user install. * Rubygems 1.6.2. * Bugfix: Ensure we are in the correct directory during git operations for macruby-head * 1.2.8 * JRuby 1.6.0.RC3 * Added default value for rvm_path. * Merge branch 'master' of https://github.com/anl/rvm into anl-master * Fix zsh completion * correcting the man files installation locations * ignoring .DS_Store files * Merge branch 'mkdir_usr_local_lib' of https://github.com/hiroshi/rvm into hiroshi-mkdir_usr_local_lib * Merge branch 'master' of https://github.com/re5et/rvm into re5et-master * packages script was broken, typo fixed. * in case of missing /usr/local/lib directory * Updated docs for get. * Added rvm get master which does the same as rvm get head for sensitive people. Moved packaging script functions into functions dir. * Updated MagLev to 25375 after fixing C-extension problems * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Added RubyGems 1.6.1 URL and md5. * Update to MagLev 25370 * Remove hard-coded /usr/local. * More progress on expanding the rails_routes script, r() also. * Added scripts/extras. * Moved rails CLI helper functions script from contrib to scripts/extras. * Added rails_routes to rails helper function r() script. * Added screen test when sourcing rvm . * Bugfix: zsh cd loading. * Remove warning from gemset copy. * Added a comment. * More cleanup in gemsets. * Ensure that rvm_gemset_name is unset for gemset copy. * Unset gemset name. * Respect PAGER while still protecting from .rvmrc based attacks. * ZSH auto_name_dirs feature is troublesome :) * Added comments and a sanity check to the trap. * Shut your trap! * Merge branch 'disk_usage_symlink' of https://github.com/ilikepi/rvm into ilikepi-disk_usage_symlink * fixed gemset completion function . * Explicit match. * Directory check on ruby gem home. * Set current to 1.6.0 * Added md5 and URL for RubyGems 1.6.0. * Adjust __rvm_fetch_ruby based on suggestions by brixen. * Add trailing '/' so disk-usage can handle symlinks * --disable-install-doc flag set by default. * Merge branch 'master' of https://github.com/pedz/rvm into pedz-master * Load __rvm_db as part of base. * Bugfix: The patchlevel tried to run away!!! * Remove GEM_HOME and GEM_PATH from initialize export. * Bugfix: load rvm reset where used. * Merged back in all my previous changes * Export rvm_ruby_repo_branch * Silence silly messages. * Removed no longer necessary n* case from selector. * Install 1.8.7 dep with a clean env * Ruby name now propigates in selector. * te hee!!! You see nothing! * Remove empty extract target directory. * Feature: Named rubies can now be any alphanumeric sequence at the end of the ruby string, no more -n necessary. In fact -n will be removed "soon". * Feature: -n/--name [name] to name a ruby, in addition to -n in ruby string. * Removed leftover function call. * Cleanup setup & initialize some more. * Take that ye variable leech! * Bugfix: keep exports in cd until the last second. * Ensuring all vars are set for project rvmrc loading. * Reorganization and cleanup. scripts/utility => scripts/functions/* * Missed an exit. * Added help for install * Bugfix: hard exit when error occurs during ruby install. * Bugfix: Proper globbing for rvm gemset import. * Seperate returned list from rubies list. * Check for matches first. * Added ncurses-dev to ruby dependencies on apt based systems. * Alter __rvm_18_compat_ruby to explicitely exclude macruby,goruby,jruby,anything not matching. * Added ~amd64 to KEYWORDS in ebuild templates. * Missed a flag for unset, simplified match() * Missed a variable for env cleanup. * Type based removal. * Removed a bit of redundancy. * Adjusted installer script sourcing. * Install check should not be quoted. * Only install 1.3.7 for Ruby 1.8.6. * Be far more precise when copying install files and directories over. * Merge branch 'rbx-1.2.2' of https://github.com/sferik/rvm into sferik-rbx-1.2.2 * Add rubygems 1.5.3 * Add rubinius 1.2.2 * Cleanup unused checksums * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Merge branch 'master' of git.overnothing.com:rvm Rename $path to $target in __rvm_rm_rf Add in a patch level for rubinius 1.2.2 Bugfix: stupididity. Rebase when pulling. Tyop. Missed a ; All rm -rf calls now use a _slightly_ safer __rvm_rm_rf with some sanity checks in place. Thanks Sven! Adding some sanity checks around rms Added sanity check to rm for tmp cleanup, suggested by sven schwyn. Merge branch 'master' of https://github.com/caius/rvm Bugfix: Manage script variable truncation. Stop ZSH warning about unmatched globs by setting an option. Revert "Supress a warning when cleaning up ./tmp under ZSH" Merge branch 'master' of https://github.com/ferrous26/rvm Supress a warning when cleaning up ./tmp under ZSH Began revising get to be able to specify a specific revision. cd will need some work to be configurable for scripts. MacRuby latest release is now version 0.9 More cleanup. Bugfix: missing variable name. Thanks tilthouse. arg*v! rvm tmp path. Properly cleanse rvm environment. Ignore .rvmrc :) Add pkg/ to gitignore. Added functions. Rollback cd. Wrappers and environments. Temp path configurable. Cleanup, aisle _ Config path configurable. gemsets & hooks. rvm_scripts_path configuration variables. Added in rvm_archives_path config. Missed a " Initialize variables. Where did they go?! Consistently use rvm_rubies_path for ruby installation path setting. Merge branch 'master' of https://github.com/MagLev/rvm into MagLev-master Removed VERSION.yml symlink. Merge branch 'master' of git://github.com/wayneeseguin/rvm Added comment to leave the eval. Call__rvm_rvmrc_tools for escaping Bump head version to 1.2.8 Updated manifest. Merge branch 'master' of git.overnothing.com:rvm Updated manifest for only the gem release files. Make scripts/migrate deal correctly with the base gemset use -eq insetad of = for an integer test New release - MagLev 25239 Merge branch 'system-installer-rev-fix' of https://github.com/fnichol/rvm into fnichol-system-installer-rev-fix Fetch more history in install-system-wide when called with --revision. Use correct gemset file name. Merge branch 'gemsets-import' of https://github.com/docwhat/rvm into docwhat-gemsets-import Merge branch 'master' of https://github.com/ferrous26/rvm into ferrous26-master Merge branch 'master' of https://github.com/sferik/rvm into sferik-master Merge branch 'master' of https://github.com/sikachu/rvm into sikachu-master Merge branch 'master' of https://github.com/xing/rvm into xing-master Merge branch 'master' of https://github.com/wt/rvm into wt-master Update for MagLev 23515 REE 2011.03 now default for ree. fixed typo that prevents cloning ruby via https Update installation procedure in README Swap find args so that find doesn't complain. Unset rvm_ruby_name when cleaning up. MacRuby nightly builds are now on version 0.10 Add 1.9.1-p431 as default 1.9.1 Non-awk way to import configuration files for gems. No grep for you sed I! Act on Christian's suggestion to use new current_gemset function in info script. Added Christian's function to utility. Formatting. 'rvm gemset list' now has a '=>' for the currently used gemset Updated usage and help. SANITYFIX: rvm upgrade [source] [destination] added full path to usermod Fix bug where "rvm gemdir" was throwing an "unknown action" error New ree release, fixed a tyop. Use a case for argument parsing in alias. Bugfix: rvm help get works as intended now. MagLev 25289. Annotations and consolidation. Removed update added get to usage output. Merge branch 'master' of https://github.com/spastorino/rvm into spastorino-master Add 1.9.2-p180 Add 1.8.6-p420 Fix to add rvm/environment/wrapper to RVM::Environment. Bugfix: allow 'rvm @gemsetname' to switch gemsets Bugfix: test for ree version # Added extra arg check. Default action to use. Moved usage from flags section into command section. alnum fool! Refactored argument parsing for more efficiency / less checking to reach end goal. * Reordered ruby check. * Reordered checks in cli parse args * Removed old matcher case. * sgr0 is safer than setaf 9. * Altered logging function definitions. * Bugfix: Adjust pattern match, thanks to thomasfedb for pointing this out. * 1.8.7-p334 is now default. * bye bye now! * Pulled logging internal. * Squeaked even more performance into the selector straight shell builtin case. * Performance improvement centered around the selector. * Merge branch 'speed-up-cd-hook' of https://github.com/tastapod/rvm into tastapod-speed-up-cd-hook * Replaced call to grep with case match to speed things up. Replaced for loop with 'env|while read' to protect env vars with spaces. * Fix call to unset causing the real result of rvmrc trustworthiness to be lost. * Minor version bump. * Added an ERROR message with an exit when JAVA 1.3 / 1.4 detected for jruby install * Added warning when java version is old when installing JRuby. * Merge branch 'master' of https://github.com/fnichol/rvm * Fixed syntax. * Merge branch 'master' of https://github.com/victorluft/rvm into victorluft-master * Merge branch 'master' of https://github.com/cr0t/rvm into cr0t-master * Extract install dir from rbconfig. * Account for Rubinius when altering rubygems versions. * Tyop fix. * Added Rubinius 1.2.1 to known list. * Allow Rubinius to change rubygems versions. * Fixed rvm_ree_options autosetter to --no-tcmalloc on Darwin systems * Added emerge line for notes. * Bugfix: when using --ree-options be sure to use the parameters passed in. Thanks to dmilith for catching this. * Update group modification support in install-system-wide for SuSE. * WTF??? Seriously? A new Repo? Save a tree, use branches! * Default ree is now ree-1.8.7-2011.01. * Rubygems 1.5.2 is now default. * Removed old maglev md5 sums * Maglev version 25223 is now default * Added jruby-1.6.0.RC2 to known list. * Setting a default ruby now creates ~/.rvm/bin/<binary> for each binary in the default wrapper directory. * Rubygems 1.5.1 is now default. * Fix gemset copy to be able to use non-complete gemset name. (I.E. @gemset or 1.9.2@gemset instead of ruby-1.9.2p136@gemset) * Fix API method typo (gemset_intial -> gemset_initial). * Merge branch 'master' of https://github.com/aef/rvm into aef-master * Reverted JRuby 1.6.0.RC1 to be the default choice for JRuby * Merge branch 'master' of https://github.com/Innova/rvm into Innova-master * Merge branch 'rvmrc_fixes' of https://github.com/tpope/rvm into tpope-rvmrc_fixes * README. * Removed unsetting of rvm_path and rvm_prefix since these are required in several scenarios to be pre-set. * Separated out RVM version from RVM API version. * Added a version file back in. * Added files back into API gem. * Damn I suck... no more lisp and ruby at the same time. brain gone * Oops! Needed to deal with VERSION.yml going away * Added jruby-1.6.0.RC1 to the known rubies * Fixed licence annotation at the end of README thanks to zenspider. * Moved from jeweler to hoe (mostly... needs check my wayneeseguin) * Moved pkg to meta * Fixed variable initialization problems in scripts/rvm * MagLev 25186 * Fixed typo in utility script * Fix typo * Prevent false matches on gems in .rvmrc bundling * Clean up run-on sentences in .rvmrc * Don't output bundle binary path from .rvmrc * Bugfix: odd tyop in help script. * Reworded rubygems line in README. * Feature: rvm RTFM * Bugfix: rvm gemset copy now works as intended. * Create destination gemset if it does not exist. * Removed contentious comment. * Updated ebuild for latest release. == Release 1.2.6 * Feature: rvm rubygems remove. * Removed obsoltete items from README. * Bugfix: correct path to log. * If revision is "head" then recenter to "master" for a git fetch. * Use builtin rubygems command to update to current during manage install. * Updated ebuild for latest release. == Release 1.2.5 * Added Rubygems 1.5.0 md5 * Rubygems 1.5.0 is 1.9 compatible, w00t!!! * How the Eff did that happen??? * Its SunOS not Solaris-x86 * Bugfix: Default rvm_promptless to 0. * Merge branch 'solaris' of https://github.com/kylef/rvm into kylef-solaris * Merge branch 'solaris-install' of https://github.com/kylef/rvm into kylef-solaris-install * jruby-head needs ant and a jdk to install (updated for Ubuntu). * Bootstrap script should pass --default flag, good catch Sutto. * RVM uses the Apache Licence v2.0. * Added "ls" as an alis for the list command, ala pik. * Make install-system-wide support SunOS * Properly detect if its a 64bit Solaris-x86 machine or not * always pull from remote repo when installing from head * * * * * * * * * * * * Bugfix: tyop, thanks to rsim for pointing it out. Added info message when trying http url. Fixing macruby-head bug. Create destination during a copy. Merge branch 'master' of https://github.com/timfel/rvm into timfel-master Slight refactoring in rvm-prompt. Allow to use characters in prompt like virtualenv for python Bugfix: logic error, thanks to lfalcao for pointing this out. Fixed a tyop thanks to telemachus. Added bootstrap_rails_environment contrib script. force re-setting of GemStone url, otherwise downloads won't work, if the URL has already been set in the env Updated ebuild for latest release. == Release 1.2.4 * WTSyntax? * Updated ebuild for latest release. == Release 1.2.3 * Added libxslt/libyaml to usage output. * Merge branch 'master' of https://github.com/sunteya/rvm into sunteya-master * Bugfix: tyop. * Added libyaml package. * Maglev 25051 is now default. * The 'rvm remove' will re-delete environments and binaries * Merge branch 'base-typo' of https://github.com/jcf/rvm into jcf-base-typo * Merge branch 'rvm-current' of https://github.com/jcf/rvm into jcf-rvm-current * Second patch by lordzork + slight syntax cleanup twards the project standard. * Applied patch by lordzork. * Removed =~ usage for older shells, thanks to cosine. * Correct a typo in a comment within scripts/base * rvm current * Default rvm_path and rvm_prefix to exported environment variables then empty string. Thanks to agreif for pointing out the issue. * Updated ebuild for latest release. * Defaulting RubyGems to 1.4.2 for allowed interpreters (MRI 1.8.X). * Doublejump! * Also escape forward slashes for awk match. * Reorder our escape sequence :) * Awww.. c'mon ... you saw them too?! * But I *like* backslashes :( * It is amazing how much one lil dot can affect things :) * Adjusted trust check logic. * Adjust for when USER is not set. * Use escape when checking trustworthiness * Version bump to 1.2.2 * Adding a packaged version of rvm and a new rvm-install script which uses the version packaged in the gem. Thanks to vkushner for the conversation :) * Missed a file. * Feature: use a user directory in order to store user settings instead of the config/ dir. This also fixes the "disappearing rvmrc" bug. * Support JRuby's .RCX kinkyness. * Added escape flag for db. * Escaping keys in the db :) * Added rvm_always_trust_rvmrc_flag to examples. * Only for ruby interpreter use svn like branch calculation. * Applying zenspider's patch * Account for possibility that rvm_path is not set. * Trust a .rvmrc file if rvm_always_trust_rvmrc=1 is set in ~/.rvmrc or /etc/rvmrc regardless of contents if it is trusted once. Thanks to yonahw for this! * Remove file before writing to it in gemset export. == Release 1.2.1 * Altering loading of override_gem. * Clear all traps upon successful teardown. Call rvm teardown on trap. * Merge branch 'master' of https://github.com/adammck/rvm into adammck * Added a check to ensure /etc/rvmrc exists before sourcing it, thanks to pedz for the heads up. * Bugfix: account for unset variables, thanks to zenspider for pointing it out. * add rvmrc test. * fix trailing space bug, and improve tests. * add minimal unit tests for 'rvm [un]export'. * add minimal docs for [un]export. * add 'rvm export' and 'rvm unexport' actions. * Make sure \n is literally printed in the .rvmrc file, as opposed to being interpolated * Bugfix: escape quotes inside .rvmrc template. * Updated ebuild for latest release. == Release 1.2.0 * Bugfix: ensure that .rvmrc files are output exactly as they are ignoring escape sequences. * Updated ebuild for latest release. == Release 1.1.13 * Fixed a daft tyop, thanks to El_Picador for pointing this out. * Be more verbose by default for users. * Increased verbosity and clarity of the .rvmrc file, also made it more DRY. * Revert to printf since log has been removed. Thanks to khasse for bringing this up * Bugfix: Nono RVM, Bad touch! * Updated ebuild for latest release. == Release 1.1.12 * Bugfix: tyop with syntax. * Ruby repository uses 'trunk' as 'master' * Install -head MRI Rubies via github. * Removed legacy rvm-install * Bugfix: Ensure archives directory exists for latest. * Removed configure env setup from manage, leaving for libraries * Added libc6-dev to aptitude installation notes. * Updated ebuild for latest release. == Release 1.1.11 * Added *.rbc to gitignore. * Comment out archflags for now. * Updated rvm-get-latest * Bugfix: rvm get latest, variable correction. * Updated ebuild for latest release. == Release 1.1.10 * Merge branch 'archflags' * Swithed install head script to use https, install latest script now checks md5. * Archflags working on packages, not quite yet on rubies. * Added some varaibles to cleanup. * Removed extra trailing slashes * Updated ebuild for latest release. == Release 1.1.9 * Rubygems 1.4.1 * Added newline as requested by daniely. * Merge branch 'master' of git.overnothing.com:rvm * Do not unconditionally call project rvmrc when cli is loaded, this is taken care of when RVM is loaded in scripts/rvm * Add in zlib-gc-fix for 1.8.7 and ree, Fixing issues with bundler installing gems. * Updated ebuild for latest release. * Adjusted rvm notes for JRuby on aptitude hosts. == Release 1.1.8 * Bugfix: rvm remove --gems X now uses full paths to avoid any possible CWD issues. Thanks to agrimm for bringing this to our attention. * Bugfix: unbound variable in cli. * Use rvm_promptless for the rvm-auto-ruby and the like to avoid hangs in things like TextMate * libruby osx arch patch for 1.9.1 and 1.9.2 * Added openssl-devel to yum distro notes. * Updated ebuild for latest release. == Release 1.1.7 * ruby-1.9.2-p136 * ruby-1.8.7-p330 * MagLev 24924 * Merge branch 'fix_test_suite' of https://github.com/txus/rvm into txus-fix_test_suite * Fix: test suite refers to unknown dir * Fix typo on rbx-1.2.0 * rbx-1.2.0-20101221 * Missed 2 sed's, thanks to gabebw for pointing this out. * Merging in patch by iLikePi. * Practice safe sed :) * Merge branch 'master' of https://github.com/cdunn2001/rvm into cdunn2001-master * Merge branch 'fix-191-version' of https://github.com/gabebw/rvm into gabebw-fix-191-version * Zsh completion of gemsets trailing rubies (#84) * What, you mean you actually want to compile something??? * config/known now shows correct ruby-1.9.1-p378 * Append to file, again thanks for the heads up cdunn2001. * Change over-write to append; same as previous change by wayne, different line. * Append to file, thanks for the heads up cdunn2001. * Updated ebuild for latest release. == Release 1.1.6 * Updated post intsall message for the gem releases. * Solaris, why can you not play nice with others??? * Altered the way PATH is cleaned to get things working on Solaris. * Make implode take into account other items including wrappers * Bugfix: Macruby gem command now respects gemsets. * MagLev 24864 * standardise the display of known rubies and their defaults eg. macruby[-0.8] rather than * Updated ebuild for latest release. macruby-[0.8] == Release 1.1.5 * MacRuby 0.8 is now default. * Added informational output when --static is used. * Bugfix: Allow rvm_static_flag to pass through. * Feature: --static for statically built MRI Rubies. Removed RVM installation from RVM API gem. * Switched to https. * Added line numbers to the default irbrc prompt * Temporary fix for the project rvmrc bug w/ path-identifier * Escape aliases in the shell wrapper, correctly export the shell variables in environment.rb * Escape a grep in selector. * Tweaked version check / exporting rvm_version. * Removed unused extra variable. * Updated ebuild for latest release. == Release 1.1.4 * Feature: 'rvm gemset list_all'. Thanks to jedmtnman. * Merge branch 'master' of https://github.com/blueboxgroup/rvm into blueboxgroup-master * Patch to resolve issues experienced with a missing rvm_path command. * Handle md5 in fetch on OpenBSD. Thanks to Andrew Gwozdz * Bugfix: When NOT root :) thanks jonathonstorer. * Switch from whoami to id for POSIX compatibility as suggested by rockyb. * gem install jruby-launcher after installing any jruby. * Added jruby-launcher to JRubys global gemset. * Further quoting fixes. * Bugfix: Properly quote when -e is called. * Added libxslt to the recommended dependencies list, thanks laomao!. * Bugfix: Clear defaults and delete alias when system is set as default. Do not output the alias deletion (twice even!) Thanks to dreamcat4 for this. * rake install macruby via rvmsudo. * Updated ebuild for latest release. == Release 1.1.3 * Merged in a tweaked version of robotarmy's OPenBSD patch. * JRuby 1.5.6 is now default. * Acted upon Dreamcat4's recommendation. * Load rvmrc when rvm is sourced. * Allow setting of rvm_tmp_path in ~/.rvmrc * Updated ebuild for latest release. == Release 1.1.2 * Merge branch 'master' of https://github.com/wingrunr21/rvm into wingrunr21-master * Merge branch 'darwin_notes_abandon_system_ruby' of https://github.com/billgathen/rvm into billgathendarwin_notes_abandon_system_ruby * rvm install goruby * Update system wide installer for Darwin support * Bugfix: 'rvm --default system' now works as expected * Reset when system is set as default. * Allow selecting git branches via --branch when installing a Ruby. * Bugfix: setting default now properly creates an alias again. rvm list default also works again. * Tyop fix, thanks to nirvdrum. * Added rvm_ruby_name to variable unset section thanks to rocky. * I usually run rvm interactively logged in as myself, but got a confusing error when I tried to have my webserver running as www-data source it to use in a setup script. Hopefully this change will make it clearer to anyone trying to do the same thing. * Updated ebuild for latest release. == Release 1.1.1 * Egg enhancement. * Ensure that when using an RVM Ruby BUNDLE_PATH is unset. * rvm gemset import output is a bit nicer. * Merge error & log files into a single log file. * libreadline5 => libreadline6 * s/git/git-core/ for ubuntu packages. * Added libyaml-dev to ruby deps on Ubantos. * Added after cd hook to latest zsh. * Added before & after do hooks. * Added before_install / after_install hooks. * Revert "a few more quotes" * When installing as user always install to ~/.rvm * a few more quotes * A quoting we will go! * Added notice upon script entry. * Yeah... I'm going to pretend that I did not just do that, join me please. * Bugfix: rvm install 1.8.7,1.9.2 * Silence grep for BUNDLE_PATH. * Bugfix: only adjust environments files if the directory exists. * I *love* it when interpreter authors are highly responsive, go brixen!!! * Check for BUNDLE_PATH before replacing. * Bugfix: remove the prefix path before configuring for rbx. * Bugfix: Remove the destination prefix path for rbx install. * Bugfix: Clean BUNDLE_PATH from environments on install. * Removed shyouhei/mputs interpreter install as it is no longer necessary or maintained given the official ruby github mirror. * Bugfix: Remove destination path when updating from github. * Updated ebuild for latest release. == Release 1.1.0 (aka 1.0.23) discontinues use of BUNDLE_PATH and global gems are now picked up by Bundler (1.0.5+). * Updated ebuild for latest release. == Release 1.0.23. Bundlercats ho!!! * No longer use BUNDLE_PATH. Three cheeers for team Bundler! w00t! w00t! w00t! * Indicated that rbx-head is default for rbx. * Add Rubinius 1.1.1 * Fix build of macruby-nightly * Bugfix: default rvm_cd_complete_flag to 0 * Changed rvm_trust_rvmrcs to rvm_trust_rvmrcs_flag=1, as it is a flag. Take Note Folks! * Updated ebuild for latest release. == Release 1.0.22 - The quirkey release. * Feature: rvm_cd_complete_flag for ~/.rvmrc. * Merge branch 'master' of github.com:wayneeseguin/rvm * Add bug fix for rvm tools path-identifier (and hence support in passenger). * Default rbx version is now head. * Bugfix: Detect rvm function load. * Bugfix: properly call "less -X" as default PAGER, thanks to lmarburger for the heads up. * Bugfix: Working function load test for both sh and bash/zsh. * Tyop Fix: it appears that visually rvm and ruby interchange when reading quickly... Thanks again to aspiers. * Adjusted wording for more clarity, thanks to aspiers. * Bugfix: Allow RVM loading detection to work with sh, thanks to David Black. * call less -X to stop the screen from clearing. * Merge branch 'master' of github.com:wayneeseguin/rvm * Tweaked the nice patch by James Blanding. * Merge branch 'master' of github.com:wayneeseguin/rvm * More traditional behavior for './install --help' * Another string readability tweak. * See the diff, rvm install ree -C --with-readline-dir=$rvm_path/usr,--with-iconv-dir=$rvm_path/usr,--with-zlibdir=$rvm_path/usr,--with-openssl-dir=$rvm_path/usr was oldskool, now it is rvm install ree --with-readline-dir=$rvm_path/usr --with-iconv-dir=$rvm_path/usr --with-zlib-dir=$rvm_path/usr --with-openssl-dir=$rvm_path/usr * bumping jruby to 1.5.5 * Some cleanup of selector. * Bugfix: gemset name persisting after failed use issue. https://gist.github.com/607116 Thanks be to george. * Bugfix: "rvm 1.8.7 test.rb" now works as expected, Thanks to Alex Chaffee * Merge branch 'master' of git.overnothing.com:rvm * * * * * * * * Bugfix: do not include /bin in GEM_PATH. Thanks to cube! Bugfix: error when "1.8" or "1.9" is used. Thanks valeri_ufo! Merge branch 'master' of github.com:wayneeseguin/rvm Addressing the concerns of portsnap. Adjust handling of CDPATH to honor new IFS value Make sure you use the unaliased grep Updated ebuild for latest release. == Release 1.0.21 * Bugfix: "rvm install 2.9.2" now fails as expected * Fixed possible format string vulnerability. * Fixes a problem where tab completion didn't work when a directory in the path contained a space. * Updated ebuild for latest release. == Release 1.0.20 * Bugfix: remove src dir if it already exists before moving extracted dir over. * Bugfix: unset rvm_ruby_package_file as well. * Patch by Darcy Laycock <sutto@sutto.net> "Convert to an array correctly." * Bugfix: properly return bison check code. Thanks to joukokar for this. * Convert to an array correctly * Suppose (and not Supose) * Added instructions for abandoning Snow Leopard system ruby. * Handle /D<Tab> cases so they don't try 'Documents'. * Fix cd tab-completion. * Added instructions for abandoning Snow Leopard system ruby. * Just finish to put comments to better docs * Put some comments in info and add comments in the #use method * Add some example in list informations about environments * The #env_contents should return a array * Added some comments in env methods (It's better for rdoc =-) * Bugfix: 'rvm rubygems 1.3.7' thanks to Matthew McEachen (mrm_adgrok) w00t! * MagLev 24566 * Stick to the most standard tool for Ruby in RVM default gemsets, users can add their own. * Backed out rvm_export_if_set, sorry teleological too big of a performance hit. There must be another way. * Enable alias complettion for zsh * Fixed: s/rvm update --head/rvm get head/, thanks to Nathan Youngman. * Updated update-head script * Updated ebuild for latest release. == Release 1.0.19 * Added scripts/get. * Bugfix: Turn off error tracing when done. * Features: 'rvm get latest' and 'rvm get head', Depreciated: 'rvm update' and 'rvm update --head' * Tweaking for when USER is undefined. * Hardcode location of sysctl on OSX, thanks to shigeya@wide.ad.jp * Updated ebuild for latest release. == Release 1.0.18 * Merge branch 'master' of github.com:wayneeseguin/rvm * unsetting RUBYLIB / RUBYOPT thanks to suggestion by khaase * SHA should be short not long * Merge branch 'master' of github.com:wayneeseguin/rvm * Updated ebuild for latest release. == Release 1.0.17 * I believe this is a bug fix * Further tweaked fetching user name. * Switched user name retrieval to "git config user.name", thanks cypher23 * re-comment cd completion code. * Manually applied patch by teleological. http://github.com/teleological/rvm/commit/21d6083db3fffc5fa92b9ea8814f3f28f7e48c7f * Bugfix: unset rvm_head_flag with ruby variables, thanks koraktor. * Merge branch 'master' of github.com:wayneeseguin/rvm * Bugfix thanks to mbarnett: Fixes an issue where cd completion will fail completely if any directories in CDPATH do not exist. * Fixes rvm update problem on zsh. * Fix Ubuntu notes. * Updated md5 file. * Commented out _rvm_cd_complete for now, unsure as to the purpose of it. * Bugfix: Account for rvm_ruby_version being empty. * Bugfix: properly compute next token for --branch * Updated ebuild for latest release. == Release 0.1.16: The NYC.rb Release. * flags should be tested as integers and be sure to account for nil * Only trigger loading of rvmrc if in an interactive shell when sourced. * Merge branch 'master' of github.com:wayneeseguin/rvm * Feature: --branch for use with git head repositories. * Moved cd autocompletion so it will really run. * More updates for --repo * Dumb dumb dumb dumb.... * Bugfix: we have the first user using --repo :) * Tweaked rvm notes a bit more * Tweaked rvm notes output for clarity. * Added a .nil? guard in case rvm_path is not set in the environment. * Fixing rvm update. * Updated ebuild for latest release. == Release 0.1.15 * Trigger any cd hooks when sourced. * Removed rubyforge as a source for rubygems and the latest ruby enterprise. * Change git-core to git; git-core now deprecated in Ubuntu repo * Fixed a silly tyop, thanks dipnlik. * Rescue LoadError explicitely for Readline failure, thanks to Alexey Antipov. * MacRuby 0.7.1 * * * * * * * * * * * * * * Bugfix: nonzero exit code when unrecognized command. Allow gemset to pass through the variable clearing. Addressed Yehudas rvm-prompt slowness query. Adjusting order of operations for ruby string calculation. slightly reverted user patch. Removed patches from openssl for now, until someone tells me WTF happened to them. Feature: rvm gemset rename X Y (for currently selected ruby) Getting this to work: rvm my_alias@my_gemset. Previously only e.g. rvm 1.8.7@my_gemset worked. Worked a bit on the integration tests. Maglev 24407. Added notice about re-setting default if user sees the error message. Bugfix: do not blindly chmod +x, thanks egyp7! Blasted formatting issues, thanks for the kick in the arse jacquesc. Updated ebuild for latest release. == Release 1.0.14 * Added man/ to gem files. * Merge branch 'master' of github.com:wayneeseguin/rvm * Merged in patch by deliciousrobots, domo arrigato!!! * Clean up. * Add a short hand to install all dependencies for ree in appropriate order. * Revert "Reamin rvm_ruby_interpreter to show current ruby on rprompt." * Ask readline to use ncurses in ~/.rvm/usr * Reamin rvm_ruby_interpreter to show current ruby on rprompt. * FIX: fail to build readline-5.2 on Snow Leopard, and may be on Leopard * FIX: wrong path to patch * FIX: missing codes to apply patches * FIX: rvm_project_rvmrc_default doesn't work * no need for -d on rm, -f ignores non existent * no need for -d on mkdir -p: checks that automatically * Copied over latest install head script. * Reversed the order of git url attempts. * MacRuby 0.7 is now default. * Updated ebuild for latest release. == Release 1.0.13 * Bugfix: postpend not prepend rvm_path for selector for system case. * Slightly tweaked conditionally add bin path. * Missed a spot with rvm_gems_path. * Merge branch 'master' of github.com:wayneeseguin/rvm * Updated ebuild for latest release. == Release 1.0.12 * grab revision from the right argument * fix path bug in wrapper wrap() * make is also required by arch * Sing along with me now folks, 'I'm a dumbass after all, I'm a dumbass after all, I'm a....' * I have been convinced of the readability difference between function declaration styles. * Merged in bash cd completion patch by albus522, thanks! * Bugfix: account for empty binary list. * Bugfix: upgrade, thanks kevwil. * Further separate out destination calculation. * Removed extra \\ * Reformatting code. * only 1.9+ requires a 1.8 compatible ruby to build. * Tweaking gemsets calculation for telemachus. * JRuby 1.5.3 is now default. * Fix disk usage and cleanup to work again with the newly refactored code. Thanks to tomyum for the patch * Fixed a tyop, thanks piclez. * Installer will now exit on any unhandled nonzero return status. * Bugfix: fixed unbound variables in installer. * Bugfix: no more "pretty slash trails" * Refactored 'rvm repair gemsets'. * Feature: rvm repair gemsets * Bugfix: Ensure that gems/@global and gems/*@ no longer appear. * Rubinius now defaults to 1.1.0, thanks for the heads up spastorino * Bugfix: rvm-prompt when jruby is used. * Bugfix: s/--/-/ * Bugfix: allow bash to list the directories for find to search. * Bugfix: Fixed order of parameters for older versions of find in post cd completion code, Thanks for the heads up telemachus. * Cleaned up upgrade script thanks to feedback from jatan. * Ensure that bin path exists. * Whoops, forgot the env! * Look ma, I am flexible! * Swap command order. * Going for the throat. * Wrap rvmsudo eval command in quotes. * Tweaked wrapper to display usage when no arguments are supplied. * Added rvm list ruby_svn_tags to help output. * Removed call to regenerate_wrappers, thanks jmhodges. * Bugfix: rvm 1.9.2 gemset create testes now works as expectd, thanks cjbottaro! * Updated ebuild for latest release. == Release 1.0.11 * Added rvm_path/bin to mkdir list for install. * Added NOTE to --passenger flag about Passenger 3. * NEVER use backticks. * use $PAGER * Tab-complete through a chain of dirs works as normal * Maintain CDPATH tab-completion with RVM's cd * Tweaked rvm repair output. * Merged in wrapper regeneration into repair. * Attempting to debug the wrapper regeneration. * Use full path for wrappers :/. This means that after rsync users will have to do an "rvm repair all". * Bugfix: rvm gemset copy X Y now works properly (tyop) * Set errtrace for installer at the top. * Default rvm_ruby_string to empty string. * adjusted wrappers regeneration * Account for possibility of no rvm_ruby_string in __rvm_run. * Some cleanup on installer, now runs under shell options noclobber, nounset, errtrace. Now respects --trace as part of args parsing. * Add gemset support to aliases * Fix bug with sourcing items in alias * Forgot the version number, lol! * Updated ebuild for latest release. * Merge branch 'master' of github.com:wayneeseguin/rvm * Applied patch from Christopher Roach, Thanks! * Outline case statements. Removed another 'echo' statement. * Removed echo statement for os_type. * Updated install-system-wide script with support for FreeBSD (tested with FreeBSD 8.1). * Merge branch 'master' of git.overnothing.com:rvm * Simple refactoring * Add rvm_ruby_api env variable to make detection in .rvmrc files possible * Hook wrapper regeneration into the upgrade process * Add wrappers to repair * List fixes, regenerate for gemsets * Add utility to regenerate all wrappers * Improved shell escaping for env * Implement a more advanced method of detecting the default rvm_path in the ruby library * Added rvm_path to env file exports. * Bugfix: --trace actually produces a trace once again. Bugfix: automatically regenerate wrapper scripts if missing. * Adjusted rbx compile to use the wrapper script for the 18 compatible ruby. * Defaulting rvm_ignore_rvmrc, thanks Cicloid. * Bugfix: Testing for directory in .rvmrc, thanks bjencks! * Initialize rvm_ruby_interpreter to first part of rvm_ruby_string if not set when entering the selector. * More cleanup. * Bugfix: rvm 1.8.7,1.9.2 gem install X * Bugfix: escape any / characters in in the match regex. * Bugfix: symlinks for default, etc now get created again! * Some more cleanup. * Bugfix: rvm 1.8.7,1.9.2 exec ruby -v * PIBRQBAS * Replaced .nitems with .compact.length * Bugfix: cleanup tracing on exit. * Bugfix: rvm 1.8.7 exec ls * Do not load completion if readline failed. * Bugfix: move maxhistsize within the scope of Kernel::at_exit * fix % to %% substitution in log script for older bash * use an alternate method to save irb history until irb/ext/save-history is fixed * Applied patch by bjencks. * Bugfix: rvm gemset delet cucumber now does what is expected. * Check in irb fix which shouldn't be needed * Bugfix: rvm package install zlib. * Whilst putting the cart before the horse can be quite amusing, reality sets in after we do not get to our destination. * Bugfix: rvm system now correctly appends instead of prepending rvm bin path. * Apply patches after running ant dist if installing JRuby Head. * Array! * Cleanup any swap files found in rvm_path, if they exist. * Missed a few variables during teardown, thanks bjencks! * Bugfix: Adjusted loading detection to accommodate for ZSH. Thanks eregon. * Added ~/.rvm/hooks/after_cd hook ability to RVM. * Simplified rvm function detection. * RVM now detects whether it is loaded in the current shell as a function when sourced. * Altered the way that rvm_loaded_flag is set for byrnejb. * Updated ebuild for latest release. == Release 1.0.9 * Bugfix: Initial gemsets are now behaving. * Bugfix: Default log path to rvm_path/log * Still working on fixing initial gemset import, commented out while debugging. * Bugfix: needed the extra level of interpolation. * Fork! Fork! *BOOM* * Bugfix: rvm alias list. rvm X --default. rvm list default. * Bugfix in alias creation, will no longer duplicate. * Bugfix: Removed [[ keyword from around md5 comand test. * Going for the throat, explicitely. * Moved tests in preparation for the separation. * Bugfix: jruby cp issue. * Explicitely export all RVM variables inside scripts. * Bugfix: Removed extra line from PATH parsing. * Removed start of line from awk, only doing a single export now. * Quote out actual_file * Do not unset result. * Updated ebuild for latest release. == Release 1.0.8 * Fixed double or nothing bug. * Almost there, double or nothing eh? * This time I have ZSH to thank for finding a bug. * Cleaned up upgraded/migrate usage(). * Missed a spot. * Bugfix: rvm gemset list. Thanks ianw! * Maglev 24209 -- Rails 3.0.0 Support * Defaulting rvm_gems_path * Ensure bin_path has defaults * Grumble. * Environment is much cleaner new. More code cleanup. * Bufix: solved the case of the missing line. * Bugfix: Fixed typo, setting defaults now works. * * * * * * * * * * * * * * * * * * * * * * * * * Missed a spot. Bugfix: prefix set in env no longer carries through to wrappers. I am an arse. I know better than to use find/replace :/ Setting source directory explicitely. Merge branch 'master' of github.com:wayneeseguin/rvm Find and replace? Yes. It is that technique where you take perfectly working code and replace it with bugs. Bugfix: location of rvm_ruby_src_path was not set. Fix zsh completion for gemset commands Fixing zsh completion syntax rvm_tmp_path no longer defaulted in global namespace. rvm_docs_path no longer default in global namespace. rvm_log_path is no longer in the global namespace Removed rvm_src_path from global exports. rvm_archives_path, some more code cleanup. rvm_config_path and rvm_rubies_path Removed rvm_environments_path and rvm_wrappers_path. Removed rvm_hooks_path from configurable. Run in parallel, saves a few seconds or more depending on the # of gems in a gemset. Removed 'info: ' prefix from info, now labels only show for other levels. Feature: rvm gemset unpack Bugfix: ruby_string() now correctly grabs the current ruby string. Removed redundant libs, as requested by the department of redundancy department. Added --trace and --verbose options to rvmsudo. bugfix: rvm --shebang inspect gem Safely strip rvm elements from the PATH. Updated ebuild for latest release. == Release 1.0.7 * Bugfix: rvm gemset create X * Bugfix: ensure rvm reload you know... reloads? * Cleaned up installer some. * Bugfix: rvm_pretty_print_flag now actually prints with colors in rvm list. * Visual cleanup on list. * Bugfix: find -iname ordering, thanks matti * Missed a spot! * Trimming down more, s#rvm_gemsets_path#rvm_path/gemsets#g * Trimming down more, s#rvm_scripts_path#rvm_path/scripts#g * Unset head_flag when an rvm call completes. * Reflect that p378 is the default in list known. * Modify default annotation based on suggestion from gitmate on github. * Set empty binaries correctly * Bugfix: rvm gemset empty now works (tyop). Added extendedglob to zsh. * The good news is I think I found the culprit. The bad news is I have to recompile 1.9.2 again to test this. * More cleanup on scripts/manage. * Carefully handle binaries array. * Fun with find, Scene I, Take III. * More fun with find and seek! * I just *love* the way CentOS keeps their systems up to date :/ * Bugfix: bashd zsh. * I need to go back to kindergarden and learn how to type. * More fun with ZSH. * Removed -G, --archives, --src path options in preparation for consolidation and "system vs user". * Removed exit on cleanup. * Some people like consistency too much :/ * removed gemset separator from global initialize. * Updated ebuild for latest release. == Release 1.0.6 * Tweak bison detection. * Another performance tweak, this time to selector which is called neigh every time. * Much work with the loco locals. * Allow ruby-1.8 in 1.8 compatible rubies. * Slight cleanup on gemset_snapshot * Went one level too deep. * rvm list much faster feedback now. * Bugfix: "rvm use/install/... jruby-head" no longer inserts the version. * Added simple CLI parsing to install-system-wide * Use rvm_revision to specify a particular git revision of rvm to install * Turns out maxdepth 1 is MUCH faster than simply specifying the depth. * ls > /dev/null * Change to an array * Account for extra spaces. * Much faster version gathering. * Explicitely remove default from set operations. * * wayneeseguin sprays aliasbgone * Ensure ruby string is set. * Ever so slowly spreading my cheeks to remove my head... * Who stole my bloody quote? Cheap bastard... * Removing usages of =~ so as to not be "idiotic", by the power of GreyCat!!! * Altered git detection. * Make configure flags immune to the mass cleanse. * Explicitely set rvm_ruby_configure_flags when possibly first used. * Bugfix: do not quote args of the regex. * Slight cleanup of rvm binscript. * Simplification thanks to ashb. * Bugfix: RVM.tools_strings('1.9.2') * Bugfix: rvm update * Updated ebuild for latest release. == Release 1.0.5 * More hashtags * tyop fix, thanks eduardohl * The world is not yet ready for hardcore bondage... * I comand thee!!! ... Why do you not listen?! * Balls out... * Push... Pop... *Poof*!!! * * * * * * * * * * * * * * * * Put back in the cwd :) Fixing an issue caused by me not having a clue about bash programming. Bugfix: Space strippers to the rescue!!! Bugfix: rvm gemset copy a@b c@d Got the lil bastard that time! '1.8.7@rvm-site gem env gemdir' works as expected Made ruby specific variables more consistent. Working on Remears request, hash tagging the installations. More progress. Merged --trace and --debug, respecting differences with zsh. Merge branch 'master' of git.overnothing.com:rvm More consolidation. Update tools with a minor fix Bugfix: __rvm_environment_identifier now returns proper env id again. Bugfix: Adjusted the way CLI arguments are parsed. Updated ebuild for latest release. == Release 1.0.4 * Bugfix: rvm gemset use X * More installer cleanup. * Removed spinner and sleep from install. While they were neat, non-interactive installs did not like them ;) * Tweaking install messages. * Bugfix: rvm gemset use <gemsetname>, thanks owen1 * Bugfix: tyop in CLI, thanks to RichGuk! * Updated ebuild for latest release. == Release 1.0.3 * Bugfix: Gemsets are now working as expected again. * Added pretty print to Upgrade notes. * Added rvm_pretty_print to rvm notes, thanks eregon. * Bugfix: Bandaids go sticky side down. (gemset sticky flag now set when expected). * Merge branch 'master' of github.com:wayneeseguin/rvm * Bugfix: global cache return value. * Quote $PATH when used with printf to defined $new_path. This allows spaces in $PATH. * Fix ZSH completion for the new command disk-usage * Fixed tyop, added consistency * Bugfix: default gemsets now import. * Let us be more direct, shall we? * Thanks to Sutto (Darcy) for pointing out the obvious. * Turns out older bash shells could not handle the redirect operator :/ * Added error handling around the sourcing of primary scripts when loading RVM. * Bugfix: ZSH did not like unset/declare. * ZSH goosed me. * Finally got around to fixing scripts/log ;) * Forgot to export PS4, thanks thewoolleyman! * Bugfix: rvm default gemsets now load properly. * Ten Thousand Lines... will give you such a crick in the neck! * Returns are now through utility and some of gemsets * More slow progress making things more robust. * Added "rvm strings" into CLI. More returns. More cleanup. * Tweaked rvmrc trust message wording. Added variable name and explicit returns to a few functions for clarity. * Speed up scripts/log by using builtins. Removed stray xtrace off. * Added command locations for bash/zsh in rvm info. * __rvm_environment_identifier() is now using strictly shell builtins, should also work in more cases now. * Default all logging to terminal to not use colors. set "export rvm_pretty_print=1" in ~/.rvmrc to override this. * Make that more of a sanity check until I track this bug. * Skip patching if it is not a file. * More headway with --patch. * Bugfix: rvm info * Arrays make me feel shifty... Disco Fever! * Bugfix: extract gem_prefix properly. Thank you sikachu! * We want to eliminate all spaces. * Ensure we are calling a binary for gem in gem_install * Updated ebuild for latest release. == Release 1.0.2 * Bash completion for help subcommand. * Escape newlines for old shells. * Add known rubies completion for install subcommand * Add bundler to ree global gemset. * Yet another space stripper... How drunk was I last night? ... * Simplifying space strippers, I was over thinking things. * Removed scripts/manpages, turns out that manpath finds it based on PATH, reduced complexity yay!!! * Commented out manpages, should be found based on PATH by manpath * Bugfix: Arg parsing in package * Turns out the match, was not a match. * wow... I really need to go back to gradeschool... * Dodge Z alias!!!!!!! * Found two more squealers * Someday the subtle differences between zsh and bash are going to drive me batty :-p * Patch splitting moved to internal. * Begone relic of the past. * Bugfix: Account for missing gemset. * BugFix: Bugfix Fixed. * Bugfix: matching in 18 compatible ruby based on new grep. Plus more cleanup. * Very slowly cleaning everything up. * Clarified the .rvmrc trust message a bit. * Suddenly, I feel like watching LeekSpin for an extended period of time... ( http://leekspin.com/ ) * Merge branch 'master' of github.com:wayneeseguin/rvm * More space $HOME friendly. * Remade symbolic links of 1.9.{1,2} global gemsets to that of 1.8.7. * Updated gemsets to use final release of Bundler. * Make __rvm_update_rvm extract correct, with thanks to loumz for pointing out the source of the problem * Bugfix: because some people are perfectionists ::cough:: dbussink ::cough:: * Updated ebuild for latest release. == Release 1.0.1 * Missed a few spots. * Consolidated path cleanup code, removed paste as it is a high profile alias target. Some minor tweaks. * Copy across bundled gems as part of the jruby install process * Merge branch 'zsh-warning-fix' * Actually commit the damn file * Merge remote branch 'origin/happy-fun-docs-time' * Update load-rvmrc reference * Add more docs * Merge remote branch 'origin/path-fix' * Simple fix to make sure rvm is added to the path, even with system loaded * Typo broke rvm list known * I encourage you to learn more about your shell every day, it will be beneficial. * A debugging we will NOT go... * Properly detect interactive sessions. * Improve ruby api trust-checking, primarily for passenger stuff * Removed the 'fun with perl' items, some people have no sense of humor. * Prevent unintentional exit code 1 when sourcing scripts/rvm * alias why dost thou hateth me so... * s/$(pwd)/$PWD/g * Add gem hook * Manually rehash whenever path is set * Merge remote branch 'origin/better-path-handling' * Handle conditionally adding rvm to the path * Updated ebuild for latest release. * RVM 1.0.0 * Fix set operations * Check trustworthiness around whole thing * Implement rvmrc loading security * Merge remote branch 'origin/switch-to-bzip' * Add bundler to rvm gemset * make rvm use bz2 for mri rubies * Merge remote branch 'origin/auto-install-bundler' * Merge remote branch 'origin/head-installer-fix' * Add check for 1.8.7 on 1.9.2-head * Make rvm automatically install bundler as needed * Rehash binaries on switch, forcing it to forget seen executables / lookup new path * Add zsh completion script * Problem with installing glib on mac os x snow leopard. Fixed by adding a -I compiler flag and setting the path for pkgconfig. Also added installation of pkg-config and gettext to glib function instead of mono function * JRuby 1.5.2 is now default for JRuby. Thanks for the heads up stepheneb. * And lo we fight the evil alias Hydra wherever a head may rear. * Updated ebuild for latest release. == Release 0.1.47 * Merge remote branch 'origin/generate-default-wrappers' * Merge remote branch 'origin/set-warning' * Make it generate default wrappers as expected * Fix rvm_project_rvmrc_default * Show a warning on set operations when passed what look like options * Merge branch 'master' of github.com:wayneeseguin/rvm * Merge remote branch 'origin/xargs-fix-dangit' * Merge remote branch 'origin/revert-set-all' * Change the default behaviour of the set operations, fix the rubies option * Make basename have the argument seperator * Add uninstall to the blacklisted action * Make manage receive the correct arguments, pass correct string * Don't allow $rvm_gemset_separator in gemset names (e.g. "my@gemset@rocks"): It works fine when you create the gemset, but fails in interesting ways when trying to delete it. * Merge remote branch 'origin/hudson-plugins' * Adjusted notes for apt based systems, thanks jmettraux. * Added 1.9.2 rc1/rc2 to known. * Add plugins to the repo * Updated ebuild for latest release. * Merge branch 'master' of github.com:wayneeseguin/rvm * 1.9.2-p0 is now default, w00t!!! * Typo in github url. * Add install system wide fixes for xargs * Bugfix: Fixed a *very* irritating bug related to cd "hanging" on exit sometimes. * fix -G, --archives, -source options * Altered rvm info to report both zsh and bash versions. * Correct restrict basename argument count * Fix installer showing the source line * Merge remote branch 'origin/rvm_bin_path-fix' * Correctly calculate paths to remove double-slashes * Add default-with-rvmrc / rvmrc for rvm set operations. * Fix minor issue with rm -rf * Blasted aliases. * 1.8.7-p302 is now default (Security Vulnerability Patch Level). * Merge remote branch 'origin/system-wide-tweaks' * Add system wide rvm tweaks * Merge remote branch 'origin/set-exec-fix' * Merge branch 'master' of github.com:wayneeseguin/rvm * Maglev 24067. * Fix set exec options * Use default rvm for rvm-auto-ruby * Updated ebuild for latest release. == Release 0.1.45 * Fix rvm_prefix correction logic * Refactor rvm migrate to take into account aliases and wrappers * Implement rvm upgrade * Merge branch 'rvm-migrate' * Implement item+alias as shorthand on rvm use for creating aliases * Cleanup how rvm_prefix works * Merge remote branch 'origin/no-hardcoded-env-path' * Implement rvm migrate * Don't hardcode rvm_environments_path inside the rvmrc * Make rvm gemset copy actually work correctly again * Added missing file append (>>) in ebuilds. * Use grep to suppress some noise when running a root installation as non-root. * Typo fix: __rvm_ensure_has_enviroment_files -> __rvm_ensure_has_environment_files * Apply ebuild changes from 99999 to template. * Remove broken and unnecessary installation of "environments/system" file from ebuild. * Added some informative comments to the ebuild. * Moved some ebuild template lines around to minimize differences between git-based ebuild and regular ebuild. * Rename variable: rvm_sandboxed -> rvm_selfcontained . * A little more cleanup. Also, please use two spaces no tabs for this project. Thanks! * Minor cleanup. * added code to fallback to http:// if git:// or ftp:// fails. This allows rvm to work behind corporate firewalls with http only access to the internet * Fixed system var not getting set correctly in scripts/maglev for OpenSolaris environment. * Apply recent ebuild template changes to rvm-99999.ebuild . * Removed "touch system" from ebuild, since rvm itself should take care of this. * Merge branch 'set-operation-tweaks' * Add optional targets for the set operations * Updated ebuild for latest release. == Release 0.1.44 * Updated ebuild for latest release. * Implement rvm_ignore_rvmrc, to do installs without rvmrc files * Move __rvm_environment_identifier back to utility to avoid conflicts. * Correctly expand rubies * Make rvm gemset copy correctly report the err with no args * Fix the ebuild * Misc tweaks to the sandbox installer * First set of work on implementing rvm_sandboxed * Fix __rvm_quote_args_with_shift * Totally not the droids you are looking for. * Merged converter by Darcy. * sh safe environment files. * Fixed ree named install * What... you want MORE? * Cleanup, aisle 3! Named installs actually compile now :) * correctly use rvm_ruby_name in blank selector * Adjust package name for ruby when name is used. * StripNzN * Feature: Named installs. * Fix rvm update --rubygems * Misc code tweaks, including converting not -z to -n * Properly expand the path for install * Install current rubygems correctly * Rename textmate_ruby to rvm-auto-ruby since it's universally useful * Fix rvm update --rubygems * MANPATH gets clobbered after rvm loads. Reversing the variables seems to help. * Bugfix: when cd fails properly report the exit status. * A single textmate_ruby for all! * update rvm opts and add snapshot command to completion * Added some sanity checks to file removals. * Default rvm flags before first use when loading. * Added no-default option to rvm-prompt * Prevent an alias of "tr" from "breaking" RVM * Removing rdoc from global and default gems. * Allowing the aliasing of digits directly. * MagLev 23913 * Added an extra line detailing what MRI/ree/rbx stand for to notes, thanks douglascamata. * Added a warning message with a pointer to docs for when irb cant load readline. Thanks douglascamata. * Temporarily reverting rvmsudo until we talk things out with thewoolleyman. * Added sanity to the patchsets installer. * Refactor how alias, docs and rubygems are invoked to be consistent * Ensure we set the path * Clarified a generating message, Thanks cehoffman! * Fyxed a tyop, Thanks cehoffman! * Improve rvm-shell to take into account .rvmrc * Implement rvm-repair * Set path variables with a check for valid path. * Updated ebuild for latest release. == Release 0.1.43 * Merging Darcys record-install-commands branch. * rvm_patches_path will be created by following lines * Implement strings on 'rvm tools' * Implement rvm snapshot {save,load} * Updated ebuild for latest release. == Release 0.1.42 * Add missing info functionality to api, fix list_strings output * Implement rvm load-rvmrc * Merge remote branch 'origin/rvm-usage' * Make rvmsudo use -E * Implement rvm disk-usage * Merge branch 'master' of git.overnothing.com:rvm * Feature: May now switch gemsets for the current interpreter via 'rvm use @gemsetname' * Refactor the way clang integration works * Escape percentages in the message * Implement --clang option when install rubies. * MagLev Palindrome Release. * Use the actual environment identifier * Revert the code to force 32bit, simplify 64 bit checks * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Merge remote branch 'origin/multiple-ruby-management' Merge remote branch 'origin/man-fixes' Merge remote branch 'origin/install-tweaks' Fix invocation of scripts/manage with multiple rubies Correct set the default rvm_prefix Tweaks to how rvm_prefix is handled in scripts/initialize Miscellaneous tweaks to the install proce Removed notice about 1.8.7 patchlevel now that it is back to latest. Thanks blowmage. Fix the install process for man pages, generate both versions Replace readline fix with one that doesn't need a patchlevel Remove archives if interrupted mid-download Add install-system-wide Add is-at-least check Refactor the way rvmrc is checked to make it reusable outside of cd Revert "Installer seems to be a bit jacked up somehow... fixing." Installer seems to be a bit jacked up somehow... fixing. Added an empty scripts/man to prevent silly error messages. Modify rvm-shell to take the optional first argument as a ruby string Fix the check on for arg count in scripts/wrapper Nice... missed the debugging comments & code from the contribution. Added mkdir of rvm_patches_path during install, thanks niw! Fix and improve openssl options FIX: spaces, missing options Merge remote branch 'pistos/respect-rvm-prefix-3' Fix implode spelling error in completion Adding manpage Fixed a tyop. Merge branch 'wrapper-tweaks' Merge of Darcy's work on rvm-shell Tweaks to wrapper generation Add backported openssl fixes to a patch Merge branch 'master' into respect-rvm-prefix-3 Miscellaneous bug fixes, namely related to exception 1.9.2 is now defaulted to rc2, w00t!!! Thanks Pistos! Tweak for the rvm install process Use correct item Simplify the md5 code md5 should have more info Make scripts/md5 work correctly on ubuntu, add md5 sum for the latest ree Add ability to override the command check in certain situations Bug fixes galore - also, use_from_path! Implement tools in the ruby api, fix a few misc bugs Add scripts/tools, implement identifier and path-identifier Since we are breaking out of the loop, this does not actually do anything on reflection. Initial Ruby API, written by Darcy!!! Updated ebuild for latest release. == Release 0.1.41 * Feature: Added 'rvm list known_strings', thanks to lenary for the idea. * Maglev 23767. * Do *not* use 1.9.1-p429. http://redmine.ruby-lang.org/issues/show/2404 * Respect $rvm_prefix when checking for root user. * corrected grammar (no comma necessary) and made consistent with other "info:" statements * Fix for wrong working dir showed on prompt when project .rvmrc is loaded. * Commented out dos2unix for now. * More misc work on fixing the build process, nameling detecting rubies * Don't mangle the supplied path in __rvm_ruby_string_paths_under * Defaulting 1.9.1 to p429 * rc1 is now default for 1.9.2, thanks for the heads up bcg. * better fix to allow users to specify patches with absolute path * Fix rvm_ruby_configure_flags so that it only replaces commas with spaces when they precede another option, thus allowing option values to contain commas. * Patch to facilitate building Ruby for a specific architecture on Snow Leopard * Use patchlevel default of 1 * Merge conflict resolved. * Copy files in to the correct man path * Simplify doc building process to remove docbook2x requirement, update docs * [WIP] Work on tweaking the build process for docs * Add progress details to the docbook process * manpath initialization a bit corrected * manpage itself corrected * installation script updated to install manpages * Basic manpage for rvm implemented. * Expand patch name support * Start of refactoring on patches support, including patchsets * Implement --patch{,es} support in rvm. * Ruby 1.8.7-p299, w00t!!! * Fix trailing s in the prompt * fixes pkgconfig bad url for curl * fixes iconv bad url for curl * Updated ebuild for latest release. == Release 0.1.40 * Merge remote branch 'origin/list-fixes' * Fix rvm list for architecture wrt gemsets * Reimplement the global cache, controlled via rvm gemset globalcache * Merge remote branch 'origin/gemset-update-and-tweaks' * Add rvm gemset update to the usage * Implement rvm gemset update and add a bit more info to set output * Refactor script/gemsets to have a usage message * Correctly generate an irb wrapper for rubinius * Use 'rbx irb' on rubinius * Start of refactoring for rbx-irb * Implement rvm cleanup * Refactor scripts/info * Start replacing common inclusion patterns with $rvm_scripts_path/base * Remove ruby binaries with rvm remove along with aliases * Check for 1.8 compatible rubies and use them if available. * Call __rvm_become before single exec. * Merge branch 'warn-on-rubyopt' * Show warning on upgrade as well as install * Warn if RUBYOPT is present as part of the install. * Merge remote branch 'origin/ruby-head-fix' * Make ruby-head install rubygems correctly * Merge branch 'install-message-fixes' * Clarify the message regarding sourcing rvm * Fix rvm use --default * Make rvm reset really unset all of the old env vars * Added libyaml-devel libffi-devel to yum based distros, thanks rosenfeld for the suggestion! * Bugfix: when disk and loaded versions differ, the message now makes more sense. * Record packages when they are installed. * Feature: package urls are now read from config/db * added rvm list gemsets, which is like rvm list rubies, but shows every gemset eh * MagLev 23673 * make rvm update respect the head flag, use http for updating from head * Merge remote branch 'origin/rvmrc_cd_refactor' * Tickets https://www.pivotaltracker.com/story/show/3870044 (rvm should revert back to the last manually set (or default version) when cd'ing to a directory that doesn't have a .rvmrc file above it.) and https://www.pivotaltracker.com/story/show/3869970 (.rvmrc should not be re-sources when cd'ing under the same project) * Version bump, 0.1.39 * Updated ebuild for latest release. * Let users configure the rubygems version to install for a given interpreter * Prevent it from trying on rubinius or jruby * Make installing different rubygems versions work * Added rubygems control script and CLI. * Fix bad variable naming * Use eval instead of calling exec directly * Work on adding rvm exec * When showing info for system, don't show the ruby section * Fix rvm gemset copy * rvm alias create name ruby should check that name isn't a ruby string * Fix set action exit code, make benchmark correctly work with sets * Fix build options for ree-head * Modified rvm-prompt to support using unicode format parameter in conjunction with other format paramters. For instance "rvm ree ; rvm-prompt u v" will now return "-1.8.7". Previously, the unicode parameter would short circuit all other formatting. * Bugfix: 'gem' command in rbx now works. * Actually fix match * Fix issues with unterminated regular expressions in scripts/match * Fixed a bug in BTU, added db_test file. * Bugfix: scripts/match now works properly again, and the tests are running again!!! * Feature: More compatibility with all shells for scripts/match. Thanks to Brian Jones for the motiviation :) * corrected patch-prefix presence checking * Merged in changes by Yoshimasa Niwa (niw). Thanks! * patch prefix handling added; README updated accordingly * vim temporary (swap) files ignorance * Bugfix: explicitely use the 1.8.7 wrapper for rbx install. * Half tolken for a half wit? * Feature: Allow common configure options to pass directly through the RVM CLI Example: rvm install 1.8.7 --enable-shared -enable-pthreads * Bugfix: gemset_pristine * Added/fixed typos for alias and fetch help docs * updated test cases for new "s" switch used to add "system" to the prompt when system ruby is in use. * Require s (system) switch to return "system" when system ruby is in use. * Bugfix: --passenger now regen's wrappers every time. * Remove invalid (it seems) rvm_debug_flag stuff in scripts/cli * Removed --jit from usage, thanks tmorini * Updated ebuild for latest release. * Let users configure the rubygems version to install for a given interpreter * Prevent it from trying on rubinius or jruby * Make installing different rubygems versions work * Added rubygems control script and CLI. * Fix bad variable naming * Merge remote branch 'origin/set-exec' * Use eval instead of calling exec directly * Work on adding rvm exec * Merge remote branch 'origin/system-info-fix' * When showing info for system, don't show the ruby section * Merge remote branch 'origin/gemset-copy-fix' * Fix rvm gemset copy * rvm alias create name ruby should check that name isn't a ruby string * Fix set action exit code, make benchmark correctly work with sets * Fix build options for ree-head * Modified rvm-prompt to support using unicode format parameter in conjunction with other format paramters. For instance "rvm ree ; rvm-prompt u v" will now return "-1.8.7". Previously, the unicode parameter would short circuit all other formatting. * Bugfix: 'gem' command in rbx now works. * Actually fix match * Fix issues with unterminated regular expressions in scripts/match * Fixed a bug in BTU, added db_test file. * Bugfix: scripts/match now works properly again, and the tests are running again!!! * Feature: More compatibility with all shells for scripts/match. Thanks to Brian Jones for the motiviation :) * corrected patch-prefix presence checking * Merged in changes by Yoshimasa Niwa (niw). Thanks! * patch prefix handling added; README updated accordingly * vim temporary (swap) files ignorance * Bugfix: explicitely use the 1.8.7 wrapper for rbx install. * Half tolken for a half wit? * Feature: Allow common configure options to pass directly through the RVM CLI Example: rvm install 1.8.7 --enable-shared -enable-pthreads * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Bugfix: gemset_pristine Added/fixed typos for alias and fetch help docs updated test cases for new "s" switch used to add "system" to the prompt when system ruby is in use. Require s (system) switch to return "system" when system ruby is in use. Bugfix: --passenger now regen's wrappers every time. Remove invalid (it seems) rvm_debug_flag stuff in scripts/cli Removed --jit from usage, thanks tmorini Remove type rvm from info, does not apply anymore. JRuby 1.5.1 Changed apt-get check to aptitude, overwhelming response that it is far superior. Commenting out rvm_history until we can make the solution more robust. John Trupianos *awesome* contribution to RVM, rvm remove now works properly w00t!!! Use ree 2010.02 Fix for zsh wrapper error Refactor the generated wrappers Misc tweaks to the install process Misc fixes and integration for __rvm_run_with_env new rvm env inherits trace flag Introduce utility functions to run stuff in a given env Rearrange where the gem import is run Bugfix: Actually add the code lines to the wrapper file. Added error checking around environment loading in wrappers. Bugfix: sh has '.' not 'source'. Added PATH to rvm info. Bugfix: If default flag is set when wrapper is called as root, link binaries to bin path. When root, default the bin path to /usr/local/rvm Updated ubuntu 'rvm notes' message. rbx-1.0.1-20100603 MagLev 23577 Merge branch 'repo-folder-tweaks' Refactor the watch rubies are fetched Make test/suites exit code reflect the result Updated ebuild for latest release. == Release 0.1.38 * Tweak md5 slightly. * Update the order of calls that create the .rvmrc * Beginnings of .rvmrc create refactor. * Merge branch 'gemset-ruby-strings' * Use mkdir -p instead of mkdir * Allow importing gemsets into multiple envs * Ensure we have the directory first * General alias / selector bug fixes. * Use subshells directly to import the gemset stuff * Fix recursion in alias - thanks to fermion for the bug report * Use --alias instead of --aliases * Add --aliases option to rvm install * Record each rvm command to ~/.rvm_history * Promote 'rvm notes' message to the top of upgrade notes. * Removed install_source_path for gemsets * Ensure remove correctly deals with the alias, ensure system has a blank environment file * Updated ebuild for latest release. * Implement 'rvm gemset prune' * Generate wrapper by default, fix shift for wrapper arguments * Use find and misc enhancements in scripts/install * Fix default and system on sets * Added header in 'rvm list known' for MRI Rubies * Refactor the way wrappers are used internally * Make that a quad espresso. * Bugfix: I need more caffene :/ * I will be attending remedial commit training next week. * Bugfix: initial gemsets pathing. * How did that happen??? * Merged Darcy's repo directory changes. * Bugfix: No longer spew errors on Importing gemsets part of install. * Bugfix: filesystem key-value db now properly handles kinky values. * Feature: May now specify default configure flags for MRI Rubies. Set in ruby_configure_flags in ~/.rvm/config/user. * grr... * Feature: Nested {default/global/gemset_name}.gems files from ~/.rvm/gemsets. * Minor version bump. * Updated ebuild for latest release. * 1.9.2 defaults to preview3 * Updated install notes for p174 switch. * 0.1.36 version bump. * Default 1.8.7 p174: 2010-05-31 13:47 <@wayneeseguin> drako: OK .. what are you suggesting to put 174 as default? 2010-0531 13:47 < drako> wayneeseguin: yes 2010-05-31 13:48 < drako> because is a p248 related bug 2010-05-31 13:48 < drako> in 1.9.1 and head-ruby rails3 works ok 2010-05-31 13:48 < drako> but rails 2.3.x wont work ok with ruby 1.8.7 >= p248 2010-0531 13:48 < drako> and since its still the stable branch * Add in log levels to shell log output lines. * allow for installing with a prefix * Merge branch 'gem-install-fixes' * Make rvm gem install act as expected, don't call out to rvm gemset install * Merge branch 'docs-in-install' * Remove trailing semicolon * Call cd . after rvm reload, casuing it to reload rvmrc * Allow users to install docs as a part of the install process * Update rvm_environment_identifier to respect system and the current state of ruby * Correct negate the bison command * Re-add the trailing newline for logging. Check for no bison and return from install. * Check for bison when installing ruby head * Remove extra commented lines * Updated ebuild for latest release. == Release 0.1.35 * Merge branch 'set_refactoring' * * * * * * * * Add newline after use statements Refactor the way set works, using rvm_ruby_strings Minor refactoring to how __rvm_environment_identifier works Typo fix in installer, thanks to noocx. unset rvm_ruby_strings inside of __rvm_teardown Refactor rvm_ruby_version's use for multiple rubies to be rvm_ruby_strings Use rvm_ruby_strings in set and clean up the variable Updated ebuild for latest release. == Release 0.1.34 * Change the way info is called, use the correct environment identifier * Fix the way ri generates doc, installing them into system * Update the notice for downloading rvm * Removed extra line on log output. * Clean up rvm install message more. * Added config/known file. * Features: 'rvm list known' now returns immediately and does not include svn. 'rvm list ruby_svn_tags' now lists the ruby svn tags available. 'rvm list known' alters behavior based on context. * Alter log output for better consumption by external tools without loosing the level. * Bugfix: If you do not have a system ruby installed rvm should load the default properly. * Added contrib/gemset_snapshot script. * Removed global gem caching. Excellent idea, however, it does not work for all use cases. * Feature: __rvm_setup / __rvm_teardown Thanks to amikula: http://github.com/amikula/rvm/commits/790cfa052702be6c3d7874af6b6646ec321b843a * Fix scripts/info wrt printf * Updated ebuild for latest release. * Feature: MRI Ruby URLs are now configurable from config/{user,db}. * Fix for __rvm_gemset_gemdir * Bugfix: Set rvm_ruby_gem_path in selector. * Tell users in rvm notes that they need 1.8.7 for 1.9.2-head / rbx. Thanks jmettraux! * Bugfix: Be much more assertive about loading the default environment. * Feature: 'rvm gempath', 'rvm gemhome', similar for gemsets. * Unset rvm_ruby_string if rvm has not yet been loaded. * Reimplement --default using alias and handle migration * Bugfix: Account for multiple lines being in the default file. * Bump version #. * Add rvm_gemsets_path fix * Initial post-install gemsets code. * Allowed gemset to pass through on empty action. * Made the post-help message more helpful. * Made post-help message more concise. * Added scripts/list. * Remove System from list. * Bugfix: 'rvm info' now reports correct environment information. * Logging output now feeds a newline at the end. * 'rvm list known' shows 1.0.0 for rbx- default. Thanks Defiler. * Bugfix: 'rvm install rbx' now properly downloads the source when the archive is not correct. * Added a missing line break. * Changed 'echo -e' to 'printf'. * Proper quoting for echo of parameters. * rvm info without parameters now runs in current env. * For Rubinius call configure with ruby configure. * MagLev 23530 * Bugfix: missing test operator * Add initialize to scripts/info * Add rmv env (with option --path) to get environment info * Add documentation built into rvm for wrapper * Implement environment files and switch symlinks for wrapper scripts * Silencing if GEM_HOME does not exist. Thanks Sutto. * Append to file instead of overwrite. * Feature: generate ri-site / ri for real this time. * Sticking with the default -client for jruby tarcieri. * Correct the json output for successful and errors, ensuring it wraps the rubies correctly * Added 'rvm help info' * Extra space after ruby version in output * 'rvm info' is now an external script callable by sections and can specify rubies.. * Adjusted rvm-prompt sed based on Sutto's comment. * Remainder of our changes from pairing this morning with Sutto. * Bugfix: rvm-prompt double dash bug in rbx, thanks be to Sutto. * Bugfix: rvm-prompt double dash bug, thanks be to Sutto. * Bugfix: rvm 1.8.7,ruby-head ruby -e 'p :t' works properly. * MagLev 23508. * Bugfix: JRuby gemsets now work properly, including 'rvm gemset list'. 'rvm gemset list' also is much improved. * Updated ebuild for latest release. == Release 0.1.32 * Added 1.9.2-head to list known now that there is a branch for it. Thanks altogether! * Bugfix: removed /bin from autoconf install path. * Beware the user aliases... Thanks be to ice799!!! * Default rbx built to use --skip-system for LLVM, thanks postmodern. * Prevent 'bad things from happening' when specifying 'rubinius', thanks tmm1. * patchlevel tweak. * You see nothing... * Rubinius 1.0.0 refactoring. * Rubygems 1.3.7 is now default. * Missed a variable change with last commit. * Hooks may now alter the current environment. Please be very careful what you place in them :) * Updated ebuild for latest release. == Release 0.1.31 - JRuby 1.5.0 fix for readers of RubyInside. * Sortof Bugfix: Adjust rake for a minor relase issue. Thanks to haruki_zaemon for notifying me of this issue. * Updated ebuild for latest release. == Release 0.1.30 * JRuby 1.5.0 w00t!!! * Updated install message for && return. Thanks to panaggio. * Updated ArchLinux MRI deps. * 'rvm gemset pristine', thanks be to jschoolcraft. * Added initial 'rvm help ruby' text. * Added initial 'rvm help rake' * Rubinius rc5 * Bugfix: Account for parse args now arg quoting. * Pass rvm_ruby_configure_flags through to rbx, thanks goes to khaase. * Maglev 23464. * Handle command line args with spaces (e.g., REE build options). * Run an 'svn switch' when updating a svn repo. * 1.9.3 is now 'ruby-head' * Removed --no-dev-docs from ree install. use ree-options instead. * MRI 1.8.7-p249 * Export rvm_ree_options. * Minor tweak to rdoc generation. * Bugfix: 'rvm use X' now prefixes gems bin directories to path also. Thanks erikh. * PATH order: gem bin:global gem bin:ruby bin:... Thanks for the great idea erikh!!! * JRuby 1.5.0RC3 * Removed --verbose from rdoc call. * Updated ebuild for latest release. * MacRuby 0.6 * Made installation message regarding && return more clear. * Minor version bump. * Beginnings of 'rvm help' * Bugfix: 'rvm gemset use X' now works properly again. * Do not unset rvm_ruby_string everywhere, it is meant to be used for scripting. * Cleaned up package. * Bugfix: package install autoconf. * Bugfix: Account for rvm_symlink_path not existing. * MagLev 23400 * Added zlib1g to rvm notes for apt hosts. * MacRuby nightlies should come from macruby.org * :) lets make this a three step process hmm? * Account for spaces at the beginning of the line also with rvmrc sanity check. * Bugfix, old exports. * Thank you Maz for your sharp eye. * Overzealous. * Better export handling in CLI, moving towards sh compatibilty. * Added Sanity checks to two more locations. * Check for users that do not read the documentation before loading /etc/rvmrc and/or ~/.rvmrc, thanks iotaion9. * Don't copy and paste folks, it gets you into trouble. Pure typing is the way to be :) * Feature: after_install hook :) Look Ma, it's already documented. * MagLev 23351. * Be silent if no system ruby is found. * Bugfix: Display system ruby correctly in rvm list when it is a symlink. * Removed extra $dir * Bugfix: rvm gemset copy. * djanowski. * Openssl version bump -> 0.9.8n * Removed creation of rvm_symlink_path and .gem/cache * Added RUBYOPT to 'rvm info' output. * Bugfix: Squished an oompa loompa. * Scaling back alias, went overboard last night :) * Time to go back to bed. * Bugfix: xdg-open detection now proper, removed OS type test. * Added xdg-open for systems which have it. * Bugfix: Don't you wish we could mute some people the same way? ::grin:: * Bugfix: rvm-prompt for system rubies, corrected awk. * Bugfix: gemsets line 311, thank you mgutz. * Features: 'rvm alias create [ruby] [name]' 'rvm alias delete [name]' 'rvm alias list' * Added docs feature. Thank you Paul Barry (pjb3)!!! w00t!!! * Logical negations are fun!!! * s/which/POSIX command -v/g * Bump zlib version to 1.2.5 * Bugfix: Adjust monitor for new set extraction. * Added libreadline6-dev and subversion as dependencies for apt. * Made rvm gem install output slightly more clear. * What do you mean you need to specify ./configure? * Might possibly add libxml2 to package. * Bugfix: Account for LoadError in irbrc, thanks to Shinzui! * More IR progress. * IronRuby 1.0 just about functional. * Maglev Update. * Fun with java. * Updated ebuild for latest release. * Bump version #. * JRuby 1.5.0.RC1 is now JRuby default. * Silence grep when not found. * damn copy paste * --ree-options --no-dev-docs default now for ree * Updated for cent 5.4 iconv-devel MIA. * Bugfix: do some more sanity checks when using a gemset. * Bugfix: Fixing the last bugfix. * Bugfix: Switch gemsets when already using one. * If gemset name was specified, explicitely use it. * Add more detail to the post-install gem installations (eg, where they are installing to). * Bugfix: 'rvm answer' now uses perl, since the universe is written in Perl. As it is obvious... the universe has bugs, and perl is the only language that can have bugs not even god could sort out. * Bugfix: 'rvm question' * 'rvm question' * 'rvm answer' now answers the question: What is the Answer to the Ultimate Question of Life, the Universe, and Everything? * Improved rvm info output. * Added zlib to notes. * Account for term type 'unknown', thanks Chad Woolley. * * * * * * * * * * * * * * * * Adjustment to gem for rbx-head. Bugfix: Rubinius is now able to use gemsets also :) Thank you luislavena! Dumbass. It's like you never awk'd before... When called with only one ruby, allow no args. Now can set rvm_verbose_flag=0 to silence set log. Made progress on IronRuby during coderpath interview. Bugfix: don't relink caches anymore. Improved output for gemset empty. Bugfix: Don't select if gem_home set. Install autoconf to rvm bin path / symlink path. Sometimes I wonder why we have copy/paste... Added variable. Added autoconf package url. Feature: 'rvm package install autoconf' Bugfix, grab the gemdir properly for destination in copy. Updated ebuild for latest release. == Release 0.1.27 * Remove .ext/rdoc if it exists, for those having trouble with it when installing 1.9.2-head. * Applied jhsu's patch. * Updated rvm-prompt tests to run rvm prompt in correct directory. Also updated 1.9.1 and 1.8.6 tests to use the correct 'head' versions * initial bash completion * I'll think about this more. * Bugfix: only warn when using sytem. * Do not store system ruby as root. * Added nice warning message about using gemsets with System rubies. * Be sure to practice safe sed... * Updated Maglev version to 23191. * Reconfigure always. * Bugfix: don't unset rvm_gem_name during installs. * Updated ebuild for latest release. * Minor CLI cleanup. * Added rvm-update-{head,latest} * Bumped minor version. * What? sed is not actually clairvoyant??? * rdoc/rake now install both to interpreter gemset and interpreter global gemset. * Change % to @ during update in default file. * Updated scripts/install. * Fixed rvm_bin_path in example rvmrc, thanks uxp. * Adjusted ncurses url, thanks agibralter. * Install rdoc/rake with no rdoc/ri option. * Install rdoc before rake. * Added 'system' output to rvm-prompt, thanks workmad3. * How'd that sneak in there? * 'rvm install rbx' now installs rc4. * Ignore dependencies when loading a gem. * Updated installer to output differently for install vs upgrade. * Bugfix: Improved check for no gem command. * Updated ebuild for latest release. * Bugfix ;) * Updated ebuild for latest release. == Release 0.1.25 * Feature: gemset now displays in info. Bugfix: 'rvm gemset clear' now works as expected. * Added unicode char for head. Thanks khaase! * Bugfix: install gemset renaming ready for next release. * Bugfix: % separator for migration of gemsets. * Maglev version 23101. * Now using @ as separator :/ ::twitch:: * Bugfix: Bugfix fixed. * Bugfix: If rvm_ruby_gem_home is not set, attempt to set it. * Bugfix: Removed extraneous } * Bugfix: Properly extract the ruby string for gemset use. * Feature: rvm_gemset_separator. Now with '+' as default. Install renames old gemsets. To keep old '%' then export rvm_gemset_separator='%' in ~/.rvmrc. * Bugfix: slow the insane logic down. * Performance: Use GEM_HOME instead of going through gem in rvm-prompt to gain gemset. Thanks priit! * Bugfix: 'rvm benchmark myscript.rb' works again. * Added --gems flag for uninstall/remove. * Updated ebuild for latest release. == Release 0.1.24 * Bugfix: Available packages are now detected correctly, thanks apotonick && NilsH for letting me know about it. * Removed global caching scheme in preparation for something sweet. * MagLev now 1.8.7 w00t! (23082) * Merge branch 'master' of git.overnothing.com:rvm * Updated zlib version. Thanks bierbaum. * Added a use to rubygems setup. * Crossing my legs and hoping not to get screwed. * Bugfix: unset rvmrc flag after create. * Thanks Wilson!!! * 'rvm gemset string' for consistency * Display gemset by default in rvm-prompt. * Added initial unicode concept for rvm-prompt. Thanks burke! * Removed --all. * Improved gemset and usage messages. * Bugfix: when use --create flag gemsets no longer complain. * Comment out some legacy cli items. Cleaned up the CLI help a bit. Thanks dreamcat4. * Fix typo in list known for 1.8.6 version. Thanks drewolson. * Merged in hellopatrick's patch for MacRuby. Thanks hellopatrick. * For JRuby s/kenai/org.s3.amazonaws/g. Thanks nicksieger. * Added ruby-head to 'rvm list known'. Thanks takkanm. * Rubinius rc3. Thanks Renaud (Nel) Morvan. * We have to practice safe sed now that BSD is out there. * * * * * * Better non-interactive operation (color terminal interaction). Try this one Pistos. The spaces for 'readability' have annoyed me long enough. Try that Pistos. Bugfix: only chmod when installed as user. Updated ebuild for latest release. == Release 0.1.23 * Bugfix: Ensure PATH includes gemset path when gemset is used. * Bumped MagLev version. * Moved the root check up higher. * Less agressive with the cache linking. * Only do the gem cache dance if a user. * Bugfix: Reflect on the action for packages. * Fix 1.8.7, ensure pathname2 is installed. * Tarball not zipball. * Updated ebuild for latest release. == Release 0.1.22 * Bugfix: Check for rvm_ruby_gem_home and set accordingly. Additionlly don't append %gemset to the existence check, it will already be in the gem home. Thanks mattdenner. * Updated ebuild for latest release. == Release 0.1.21 - Many gemset bugfixes. * Bugfix: rvm gemset delete now works as expected. * Bugfix: 'rvm gems use X' now properly sets up all env vars. * Bugfix: 'rvm gemset delete X' now works again. * Bugfix: 'rvm gems use X' uses X again :) * Bugfix: 'rvm gemset use X' will not double X. Bugfix: 'rvm gemset use Y' will no longer display an error message about the ruby string. * Feature: rvm_gemset_create_on_use_flag=1 in ~/.rvmrc * Bugfix: s/gems/gemset/ in error messages. * More ironruby progress. * Or maybe not. * Ironruby might work now. * Progress with ironruby... * This is the way it *should* be however ... no comment... * Bumped ironruby's version to 1.0-rc2 * Bugfix: libraries has been moved to package. * Cleaned up CLI readme slightly. * Added full path to md5 on Darwin in fetch. Thanks shigeya. * err ::cough:: /usr/ ::cough:: * Full path to OSX installer for macruby. Thanks shigeya. * Updated ebuild for latest release. * Bugfix: Fix /sbin/md5 for Darwin based systems. Thank you very much shigeya! * Bugfix: 'rvm package ....' under zsh. * Updated ebuild for latest release. == Release 0.1.19 * Updated mono package function. * Rounded out new package feature. * New API: 'rvm package {install,uninstall} {openssl,zlib,readline,iconv,etc...}' * Found that blasted missing 's'. * Bugfix: gemset not gems in set script. Thanks drewolson. * Initialize. * Source the utility functions. * Bugfix: Function naming error. * chmod certain scripts during install. * Make libraries executable. * Export in the examples. * Check for existance before grepping. * For root installs, use the rvm_path for global gem cache. * Bugfix: Libraries output no longer occurs when rvm is sourced. * Bugfix: Don't source libraries, it's now external. Thanks Jimmy Baker. * Merged Pisto's ebuild update. * Adjust where rvmrc gets loaded for package managers. * Advise users to get head often via 'rvm update --head'. * Fixed a tyop in examples/rvmrc. * Only do 'make' not configure for JRuby < 1.4. * Bugfix: For set/do actions if only one ruby is specified only do that ruby. Bugfix: when -S is used don't quote the args, thanks to aslakhellesoy. * Bugfix: missed a spot. * MagLev version 22907. * Added 'rvm seppuku' in honor of tsykoduk who can't spell so it saved his life. * Bugfix: 'rvm_gems_select' -> rvm_gemset_select * s/gems/gemset/g Thanks everyone for such a decisive vote. * Defaulting 'rvm list' to 'rvm list rubies'. * Do not try and use log script during implode after removal :). * Bugfix: global gems cache setting is now exported. * Enhanced the error message. * Bugfix: exit not return from script. Thanks TecnoBrat. * Added tracability to extracted set actions. * Added tags file to gitignore. * Heh... might need that. * tyop fix for preifx. * Made install message about the return statement more clear. * Moved 'do' actions to external script (set). Refactored to allow for rvm_prefix for package managers. * Bugfix: Show gemset for do actions. * Adding ebuild for rvm-0.1.18 == Release 0.1.18 * Renamed sticky-gems to sticky * Removed rvm_path code from installer which should not be set during install. Install is 'black and white' * Feature: Now you can empty any gem dir, not just for a gemset. * Was too agressive with last commit. We still want to use gemsets :-p * * * * * * * * * * * * * * Bugfix: GEM_PATH now gets correctly set for rubies without an actual 'version'. Removed warning message, was in the wrong place. Corrected caps of GemStone in readme. More work on gems actions. Fixed capitization of GemStone. Added maglev-head to 'rvm list known' Bugfix: removed double negation. Bugfix: properly detect a ruby string interpreter component. Feature: 'rvm gems create' Added error handling to __rvm_strings (thanks dreamcat4). Began working on the new gemset interface. Adjusted wording from --all to known for rvm install. Feature: New list functionality. Feature new strings functionality. Upgrade installers to rubygems 1.3.6 Make the rvm rubies subcommand more helpful Added installation warning when 'return' is detected in .bashrc. Adding ebuild for rvm-0.1.17 == Release 0.1.17 * Added latest maglev md5's * Bump maglev version to 22891. * Do not install rubygems for ruby-head. * What is with me and my inability to spell? * Tweak path logic slightly. * 'rvm update' no longer attempts to install from a gem. Now downloads and installsthe latest stable release tarball. * Adding ebuild for rvm-0.1.16 == Release 0.1.16 * Bugfix for the last Bugfix ;) * Bugfix: Search global path for 'do' actions. * FreeBSD deviates from the norm just like OSX :) * 'rvm gems import/export' instead of 'rvm gems dump/load' * Feature: 'rvm gems copy X Y', thanks to my UnderpantsGnome. * Bugfix: Installer fixed again. * dirname of course! * change to the location of the install file. * Added loading of rvmrc before path calculation. * Removed source_path using $0 * Adding ebuild for rvm-0.1.15 * RVM Release 0.1.15 * Allow --sticky_gems from command line. * Bugfix: better gem command detection. * Adding ebuild for rvm-0.1.14 == Release 0.1.14 * Bugfix: careful now. * Stricter checking. * Bugfix: Missed a spot for global gem cache. * Ensure symlinks are correct. * Refactored global gems cache to be located in $HOME/.gem/cache/ * Bugfix: Remove archive if it fails checks. Feature: Initial bundler support. * Bugfix: rvm gems delete. * Updated yum based notes. Thanks RubyPanther. * Feature: 'rvm X --rvmrc'. * Adding ebuild for rvm-0.1.13 == Release 0.1.13 * Adjusted install message to be more explicit about the return. Adjusted rbx's installer. * Turns out it was the previous 1.8.7 install that was jacked, not the rbx installer. * Bugfix: remove spaces in filenames for rvm gems load. * Tweaking rbx install. * Slowly improving gemset functionality. * court3nay is correct, we want \s * Bugfix: rvm gem install t* now works again ;) * Removed empty file. * Install now exits on failed patch. Error command output tweaked. * Adding ebuild for rvm-0.1.12 * Patch with p0 * Bugfix: rvm install X --patch Y now patches :) * Feature: Cleaned up 'rvm list' * Add some more output so that you know what's going on when a gem is already installed. * Bugfix: 'rvm gems load X' as well as 'rvm gem install Y'. * Oh man, that was a very sneaky lil buggar... * Sometimes I am so dense that I myself don't realize that I'm completely daft :/ * I suffer from accute mental deficiency :( * Need more caffene... * A refactoring we will go... A refactoring we will go... * Perhaps it's better to just let things go sometimes. * Two installs for the price of one * Bugfix: 'rvm gem install X' should now actually install X * Altering how gem path & home are passed for gem install. * Switch the unsetting of the patch specification to the global variables. * Refactored libraries code. Added rvm_ruby_patch exports. * Removed completion script. * Bugfix: rvm reset now clears default properly. * Bugfix for 'rvm gem install X' dealing with GEM_PATH setting. * Added proxy ability for rubies fetching. Thanks Jadefalkner. == Release 0.1.11 == Release 0.1.10 * Bugfix: Fixed tyop in variable name. Fixed extra space issue. * Bugfix: PATH correction. Thanks UnderpantsGnome. * Bugfix: Fixing the last Bugfix correctly. * Bugfix for zsh on gems load. Began adding 'rvm install mono' - not done. * Bugfix: Macruby 0.5 == Release 0.1.9 * * * * * * Bugfix: 'rvm install macruby' now installs 0.5 instead of nightly build. Is a direcotory and not a symlink. Fixed pathing for mput. Added test if directory is empty. Bugfix: globbing in zsh is unsettling. Documentation updates. == Release 0.1.8 * Bugfix: Separate directory and symlink logic. * 1.8.6-p399 now default. * Removed tracing. * Bugfix in site docs, thanks to wmadden. * Bugfix: rvm gems load now properly skips gems that are already installed. * Wow, that was a challenging bugger to track down. * Updated CLI help with more information. Bugfix: rvm gems load now works again. Feature: rvm gems load now installs gems very fast from cache. * Added shell to output. == Release 0.1.7 * p398 is now default for 1.8.6. Thanks Kirk Haines. * Removed '--no-rdoc --no-ri' as default. Set rvm_gem_options in .rvmrc if desired. * Added ebuild for 0.1.6. * Added GEM_PATH to info output. * Bugfix: Use the proper variable for global gems paths. * Bugfix: Removed extra slash from shebang for hooks, thanks haruki_zaemon == Release 0.1.6 * Update default 1.8.7 to p249. * Thank you Pete Nicholls. * Bugfix: Ensure that cache directory exists. * Added ebuild for version 0.1.5 . * Merge branch 'master' into ebuilds-nice * Merge branch 'master' of git://github.com/wayneeseguin/rvm == Release 0.1.5 * Careful not to nuke system gems cache. * No! the other left! * Bugfix: So system rubies matter? ;) * Updates to all ebuilds, including 0.1.3, 0.1.4 and "edge" (git) versions. * Updates to all ebuilds, including 0.1.3, 0.1.4 and "edge" (git) versions. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Merge branch 'master' of github.com:Pistos/rvm * Update maglev's version to 22816. * Bugfix: fun with zsh ;) * Merge branch 'master' of git://github.com/wayneeseguin/rvm == Release 0.1.4 * Added filesystem permissions check to rvm debug. * Ensure that %global gets into path. * Tweaked verbage. * Bugfix: global gems dir, no blind move. * Feature: cache md5 sums on successful download. * Global gem cache :) * Features: %global default gem set. symlink of each ruby's interpreter default gem set to ruby_string/lib/ruby. Thanks UnderpantsGnome for the %global idea. * Site update. * rvm now creates symlinks to gem directories in rvm_ruby_home/lib/ruby/1.8 for example. * Add patch dependency notice. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Bump LLVM version. * More tweaking of rvm_path for Pistos. * Mental Breakdowns for fun and profit. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * putting it back :) * Merge branch 'master' of github.com:Pistos/rvm * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Adjusted default path again. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Adjust order of defaults loading. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Moved scripts detection code, added defaults. * Thanks Justin Smestad * Thank you Justin Smestad for your support! * Trying adding in a default fallback for rvm_path. * Upgrade MagLev version. * Run notes from cwd. * Added rvm_scripts_path to install block. * Site updates. * Honor rvm path for irbrc. * Merge branch 'master' of github.com:wayneeseguin/rvm * Ensure log directory exists for nested logs. * Added rvm irbrc processing to post_install. * Merge branch 'master' of github.com:wayneeseguin/rvm == Release 0.1.3 * Added ebuild for version 0.1.2. * Added Maglev 22780 checksums. * Added MagLev 22780 Added rubygems update when new ruby gem home is created. * Feature: 'rvm install ruby-head'. * chose MRI SVN repository when install with head option * Merge branch 'master' of github.com:Pistos/rvm * Merge branch 'master' of git://github.com/wayneeseguin/rvm == Release 0.1.2 * Site update. * Bugfix: better handle ruby log paths. * Bugfix: Append to log when running a command. * Bugfix: directory creation during installer. * Added comments for all utility functions. * Added 'rvm rubies' for use with scripting. * Use the redist-libs as the source folder for Ruby libraries when copying IronRuby files after building. * Fixed a mistake in the manual merge performed in commit d471bb9. * Fixed a regression introduced after commit 12221fe that broke the recognition of a proper mono version to build IronRuby from the Git repository. * updated to Ruby Enterprise Edition 1.8.7 2010.01 * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Adjusted wrapper scripts. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * MagLev update, symlink gemstone dir. * Pedantic formatting for jruby in rvm list. * Consistent formatting. * maglev is *always* x86_64 * Bugfix: don't exit out when mostly done with MagLev install. * Merge branch 'master' of git://github.com/wayneeseguin/rvm == Release 0.1.1 - bugfixes. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Removed sourcing of .rvmrc / etc/rvmrc. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Tweaking init for install. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Add env vars to install trace. * Enable install tracing. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Bugfix: destinkerifying. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Bugfix: smelly elif. * rm -rf rm -rf. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Moved stored system/default into config/ from rvm_path * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Only show manual instructions if not installing as root. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Quick, pull your pants up the boss is comming * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Added another sanity check. * Updated binscripts/rvm * Bugfix: 'rvm install jruby' actually works now :) * Bugfix: 'rvm install jruby' now sets the correct archive extension. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Merge branch 'master' of github.com:Pistos/rvm * Bugfix: maglev-head added demo key. * Site update. * Updated sha1's for MagLev on Linux. * Copied /usr/portage/skel.ebuild for first ebuild. No changes yet. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Updated rvm-prompt to be more 'bare'. Thanks Pistos :) * Bugfix: issue a warning and point to docs when 'rvm gems' without arguments is used. * Added gems to help output, thanks technicalpickles. * Minor installer tweaks. * Added 'rvm_sticy_gems' setting for ~/.rvmrc file. Tweaked maglev-head. * Updated directory creations. * More updates for maglev-head. * Added new GemStone sha1. Fixed a logical bug with maglev-head install. * More MagLev tweaking. Now workign on getting 'maglev-head' working proper. * Added maglev-22725 sha1. == Release 0.1.0 * Added maglev to usage output and list. * Updated installation notice * Silly rabbit... debugs are for developers... * Shebang adjustment. Site update. * Added migration piece for rubies so that people aren't caught off guard like with the gem directory change. * Updated MagLev version. Fixed a few items I missed with last commit. * Initial refactoring of rubies into $rvm_path/rubies * Final pre 0.1.0 release allowing for full MagLev functionality with gem install. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Minor tweak for Pistos. * Silence gemstone check for MagLev. * Bugfix: Only start stone for maglev once. * Updated MagLev verison. * Bugfix: 'rvm gems load' now works under zsh as well :/ * Fixed a tyop * 'rvm install ree' now properly extracts with the correct extension. * More work on MagLev support. Added check for running gemstone. Added check for setting version based on ruby string digits piece. * Tweaked notes to include release name on Linux. * Update 1.9.1 to default to p378. * Bugfix: removed z in tar's where piping through gunzip. Thanks to jfsworld. * Added 1.8.7-p248 md5. * If rvm_project_rvmrc=0 then don't even hijack cd. * Fixed maglev gemstone extraction * For now always nab gemstone. * Removed extra } * Updated to new MagLev url scheme. * Updated maglev urls. * Changed maglev to download tar.gz * Switched tar extractions to work on Solaris. Updated install doc. * * * * * * * * * * * * * * Added start to use maglev. Missing [ Only extract gemstone on head. Only download gemstone for -head version. Minor bugfix. Initial working maglev, no head. MagLev precheck script working. added maglev prereq script. Initial working 'rvm install maglev'. Several things need to be done before releasing maglev. Bugfix: syntax error, daft man coding. Bugfix: Extract on force if already extracted. Beginning maglev code. grr. Bugfix: rvm gems load for path to gem file no longer emits an awk error. Thank you very much, Robert Hunter! == Release 0.999, getting very close to 0.1.0 * Added some exit points to rbx install for error cases. * Site updates. * Upgraded rbx. Several other fixes and patches. Thanks awesome users! * Site Updates. * Removed the --jit from usage which is no longer used. Use --enable-llvm instead. * Feature: sticky gem sets are now disabled by default. Set 'rvm_sticky_gemsets=1' in ~/.rvmrc to enable. * Bugfix: rvm gems delete should now work. Thanks jfsworld! * Bugfix: MY_RUBY_HOME in default file greps were adjusted since export was moved to beginning of line. Thanks jfsworld. * Bugfix: rvm install rbx/rbx-head. * Updated install message for zshrc instead of zshenv. * Altered rbx llvm code based on feedback from Evan. llvm is now default so the option for rbx is --disable-llvm. * Bugfix: 'rvm default' now works as intended. Thanks rolfb. * Switched to using match script inside mono install section so that older bash shells can still run. Thanks tibra. * Bugfix: Don't fetch version when --head is specified for macruby. * Abort macruby-head installation if install_source exited with error code. * Make llvm building opt-in for macruby via --enable-llvm flag (for now). * Add libraries to manage script. * How'd that get in there? * Propigate default through selector. * Propigate default from CLI. * Bugfix: install to exit upon encoutering it's first error. * Tweaked install message slightly. * Bugfix: rvm gems delete now works again. * Bugfix: 'rvm gems name' works now. * Feature: 'rvm gems clear' * Bugfix: rvm gems list. Thanks jpalardy. * Merge branch 'master' of github.com:wayneeseguin/rvm * Added export of rvm_hooks_path. Thanks jpalardy. * Corrected a few typos in the site's content * Bugfix: s/rvm_dir/rvm_path/g * Thank you Jack Dempsey. * Bugfix: always hit ruby for version string instead of current binary for 'do' actions. * Updated 1.8.7 in rvm-list * Changed default 1.8.7 to p248. * Changed default 1.8.7 to p248. * Thank you Jonathan Palardy. * Added git-core to apt based hosts notes message. Thanks racan. == Release 0.0.99 * Added rvm source script test for website. * Adjusted formatting of 'rvm list'. * More tweaks to install message. * Feature: './install' no longer touches rc files. Pass --auto to installer in order to have it touch the rc files. Thanks agib. * Option: rvm_gem_options ; default: --no-rdoc --no-ri * added extra sanity check to gem install * When root created default AND symlink both. Fall back to /usr/local/rvm/default when selecting default. * Extracted hoooks to external script. Improved cd logic. * Added warning to install & documentation not to return from .bashrc. * Bugfix: jruby-* in rvm list now correctly does -v on the ruby itself. * Bugfix: if a file name is given during dump, honor it. * changed exec to eval for rvmsudo. * Bugfix: only create ./log if using it. * Bugfix: whoops, those are variables? * corrected variable placement. * Adjusted prefixing for rvmsudo. * Added line padding around 'rvm --version' * Bugfix: when no gem home set rvmsudo should not fail. * Return to original directory after update. * Added spaces before & after logging messages based on Yehuda's recommendation. * Merge branch 'master' of git.overnothing.com:rvm * Detect interactive vs non-interactive and adapt logging output based on interactivity. Thanks agib & egyp7. * HOME rvm overrides system. * Don't mkdir on specs * Let's try initializing rvm's variables. * Switching to a different tactic. * Silence errors when detecting. * Merged. * Attempting to fix the detection of an installed gem. * Tweaked gem installed test. == Release 0.0.98 * Added optional trailing slash. Thanks dreamcat4. * Removed quotes from regex. * Working on adjusting the installer with dreamcat4 * merged an extract of dreamcat4's commit * Manually merged nrk's patch for BASH_REMATCH check. * Manually merged nrk's patch for pwd fix. * Manually merged fistfvck's commit 949ca1402f1d8fb491e7eafdf661205da388123a. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Added a missing LF for notes related to JRuby on systems running pacman. Tweaked initializer based on dreamcat4 suggestions and some cleanup. Added messages for IronRuby to install notes. Added IronRuby to the README. Support for building and installing IronRuby from the official git repository (Mono >= 2.6 is required). Merge branch 'master' of git.overnothing.com:rvm Feature: rvmsudo X for executing X in context of current rvm selection. Bugfix: adding HOME .profile to correct zshenv. Added mkdir -p to install script for rvm paths. Bugfix: 'rvm gems load' works again as well. Bugfix: no more double extraction for jruby. Bugfixes: rvm install jruby. switching more back ... Added message to 'ant dist' build line. Reverted more items. Bugfix: ant dist on jruby-head. Put back rvm-prompt :/ Bugfix: jruby always run ant. Added JRuby message to install notes. Added --{disable,enable}-{llvm,jit} cli flags. Bugfix: JIT logic. More tweaks to rvm rbx install. Nuked some unnecessary codez. That should about do it for 'rvm install rbx' Progress with rbx however... how do you specify install target for package? Trying a different install on use approach. Trying a different install on use approach. Take that Scyllinice! Well this is fun, switching back around. What trace? I see no trace? Bugfix: Adjusted ruby string interpreter matcher. Added debug messages to gems actions. Bugfix: properly restore rbx's ruby string. Bugfix: rvm_install_on_use_flag=1 in ~/.rvmrc works again. switch from $interpreter/$versin to $ruby_string for gem dirs. == Release 0.0.97 * Documentatino updates. * Bugfix: 'rvm X gem install Y' now works, w00t * Yes folks, zsh IS better at emitting a stack trace :) * Bugfix: Installing gems via 'rvm gem install X' * Bugfix: I just found out the which command on OSX has different options than on Linux :/ * Merge branch 'fix_rvm_ruby_do' * Removed debug statements. * Bugfix: account for plain old ruby in the ruby string :) * Bugfix: variable has regained its $ * Bugfix: 'rvm remove reeee' no longer tries to remvoe all rubies. * Feature: Use default set in $HOME first then ruby path. * Bugfix: only run exract for jruby if not installing jruby-head. * unset loaded flag during reload. * switch .profile and rvm sourcing order * re-feature: Added back the sourcing of .profile if it exists. Began cleaning up bash scripts. == Release 0.0.96 * Features: rvm X --editor : creates rvm_path/bin/editor_X symlinks rvm X --passenger : creates rvm_path/bin/passenger_X symlinks rvm X --symlinks smurf : creates rvm_path/bin/smurf_X symlinks * Merge remote branch 'origin/fix_rvm_ruby_do' into fix_rvm_ruby_do * fixed 'File Not Exist' error, when rvm_do. * Merge branch 'master' of github.com:wayneeseguin/rvm * Removed --enable-shared as default on recommendation of Aman Gupta (tmm1). * Rubinius: LLVM is enabled by default; flip --enable-llvm to --disable-llvm * Initial support for IronRuby's binaries. NOTE: the current download URL is temporary and it might change in the future. * The user might not have curl installed, so we should prompt to install curl in the notes section * Bugfix: rvm -e 'puts 6 + 7' should now work. * Bugfix: silence error output from ls. * Thank you Scott Clausen! == Release 0.0.95 * Feature: rvm now behaves the same way when logged in as root and user. To set a system wide default ruby now do 'rvm X -default' when logged in as root * Bugfix: --enable-shared not --enable_shared, thanks saimon! * Minor version bump. * No longer run irbrc on select. * Minor adjustment, --enable-shared. * Default compile flag is now --enable-shared=yes unless overridden with -C ... * Bugfix: 'rvm list' now shows proper architecture strings. * Bugfix: silence another which ruby call and also test for executable on system ruby. * Bugfix: Check proper directory and script for root install, additionally ensure rvm_path is a directory before attempting to load rvm. * Minor version bump. * Set PATH after symlinks for zsh to rehash. * Bugfix: 'rvm gem install X' works again after extracting gem actions to a external script. * Have gems load use current set / exported environment. == Release 0.0.92 * red is the new green ;) * Only call colors once per color. Set rvm_ruby_gem_home if it is not set. * Set gem_args. * Missed a rename with last commit. * Properly reflect on the gems(et) file. * the external gems methods should use the environmental ruby. * Sometimes, I see dumb people. Then I realize I'm looking in the mirror. :/ * Who commented out that shift? :) * re-added load action * Bugfix: 'rvm gems load' once again loads the gems(et). * Bugfix: export configure flags for manage script. * Added code to get 1.8.5 to compile on all systems, including ones with newer readline & openssl :) Thanks khaase! * Feature: Added post-gem-install message. Thanks tmm1! * Default Change: per-project rvmrc code to switch to default/system on exit is now opt-in instead of opt-out. == Release 0.0.91 * Bugfix: 'rvm update' now tries current ruby first. Bugfix: 'rvm install' does not imbecillically use the same code as initialize and startup. == Release 0.0.90 * Bugfix: rvm gems(et) commands now work again. * Site Updates. * Bugfix: rvm install X for libraries now works again, broken in 0.0.89 * I am so incredibly daft sometimes :( * Over zealous * Attempting to improve rvm_path logic. == Release 0.0.89 * Feature: Monitor files in lib/ and app/ directories. This might need some more polish. * Feature: md5 checksums now happen so that archives are not re-downloaded. * Bugfix: rvm scripts path looks around now before gettings set if not already set. * Site updates. * Added user tag ability to rvm ruby strings for future requirement. * Site updates. * Site updates. * Feature: gem actions are now in external scripts. * libraries are now uninstallable. * Bugfix: check if not null, not for equals 1 * Added rvm/usr path detection. * Added 1.9.1-p376 to rvm list --all * fixed 'File Not Exist' error, when rvm_do. * If rvm_archflags=1 then set rvm_make_flags_flag. * Bugfix: rvm runs extract even if archive already exists. * Made __rvm_make_flags opt-in via rvm_make_flags_flag * Updated 1.9.1 default patchlevel to 376. * Add curl to 'rvm notes' * Moved do all case to use shell builtin glob instead of ls. * Adjusted for config/user during install. * fixed __rvm_update_rvm * Bugfix: nailgun now compiles for jruby. * Bugfix: JRuby rake & gem now work as expected out of the box. * Bugfix: Run extract after package fetches only. * Bugfix: moved 'rvm_remove_ruby' into the external manage script. * Committing Rolf's mute button :-p * Site update. * Thank you Konstantin Haase! * Removed trap for zsh. * Finished extracting installer to separate script. * Site Update. * Site update, thanks Erik Hansson! * Feature: 'rvm fetch X,Y,Z' works. * Minor version bump in preparation for a release. * rvm_fetch improvements * Began working on 'rvm fetch' function. * Site update. * Bugfix: Install message no longer shows awk output, notes cleaned up. * Adjustment: rvm gems load switched colors and message around to make it more natural. * Bugfix: jruby install now correctly symlinks the jbinaries to regular and no longer alter's their shebangs. * Removed the run flag. * Adjusted the version output during install. * Removed a failed attempt at a self aware script ;) * Evil slash... begone! * Tweaked installer for new binscript. * script vs run logic. * Clear!. * Knit three yank six. * Try one pull two. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Provide more information during the installation. * In Darwin, explicitly use system's "basename" command. * Feature: rvm_symlink_path now overridable and defaults to /usr/local/bin * Extracted cd to sorced script. * Feature: Project specific rvmrc files now switch back to default and/or system rubies when exiting a project directory. Additionally they can now be toggled off by placing 'rvm_project_rvmrc_default=0' and/or 'rvm_project_rvmrc=0' in the ~/.rvmrc file * Bugfix: rbx_url * Site updates. * Removed debugging flags. * Tweaked monitor with a file check. * Added monitor page to site. * Bugfix: rvm reload now correctly reloads and does not go loopy. * Bugfix: break in case? Really? ... * Initial thoughts on patch support. == Release 0.0.86 * Added a simple bootstrap script to the documentation. * scripts/hash now executable in preparation for future use. * Bugfix: system for rvm list now shows up properly when exists. * Feature: ~/.rvm/config/user now available for user defined settings and defaults. * Site updates. * Adding config/md5 sum file. * Updated examples/rvmrc file to be current for the project. Fixed 'rvm_temp_path' to be 'rvm_tmp_path' as expected. * Bugfix: More tweaking of the rvm load. * Bugfix: scripts/rvm does not re-source if rvm is already loaded. * Bugfix: added missing ; then * Site update, thank you Vladimir Sizikov. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Added tracability to monitor. Minor version bump after 0.0.84 release. Minor version bump. Bugfix: Be sure to include files right in the test/ and spec/ directory also. Bugfix: 'rvm reload' now works again :) Feature: 'rvm <ruby string> monitor' now works for: rspec,shoulda,test/unit,... Feature: 'rvm <ruby strings> monitor' now works for spec/ Feature: 'rvm install rbx' now installs Rubinius 1.0.0-rc1. Bugfix: 'rvm install mput/shyouhei' now clones the proper url Bugfix: shebang line now sets correctly. Bugfix: Correctly set rvm_path for system only installations. Missed a spot for CFLAGS adjustment. Allow CFLAGS and LDFLAGS to be specified by environment. Bugfix: silence error messages from the command. Site updates. Bugfix: Logic was negated for finding gem command. Bugfix: Silent gems select. Bugfix: subshell not string :/ Adjusted spacing for 'rvm notes' Feature: 'rvm notes' now outputs the same notes as spit out during rvm install. We really are not interested in the output of 'which gem' for testing purposes :) Adjusted install message for ubuntu. Added message for list when no system ruby installed. gems select should silently return if gem missing. Added gem check to gems select Alter checks. If ruby & gem do not exist, skip default setting. Skip gem actions with an error message if no gem command found. Bugfix: Added check for source directory during install. Added check for gem existing for the case when no ruby exists. Bugfix: Account for the case where there is no current ruby. Bugfix: Account for the case where there is no current ruby. == Release 0.0.82 * Added site/tmp/dependencies to gitignore. * Bugfix: installer loading logic. * Site updates. * Added XCode version & update message to install. * Send error & fail messages to stderr. * Added array functions. * Extracted monitor to external script, will finish implementation later. * Feature: Added a few hooks, most importantly ~/.rvm/hooks/after_use * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Altered 'rvm list' output to be more clear. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Removed subshell after nice command. * Bugfix: properly copy binscripts to $rvm_path/bin/ * Bugfix: running -v against an existing script. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Feature: rvm_ruby_mode now propigates to the ruby -v output on the do line as well as the ruby string output. * Bugfix: Properly pass mode, do not store in rvm_ruby_args. * Feature: Ability to specify a ruby string 'jruby-m1.9' in order to startup jruby with --1.9 mode. * Tracing is like divining with entrails! * Bugfix: do not unset all variables. Bugfix: Adjust the rvm loading logic. * buahahahaah found you you lil bugger! bug ! bug ! ... SQUISH * Bugfix: Initialize issue during install. * Removed debugging line. * Bugfix: Installer actually works now when no rvm is present :) * Bugfix: Better return logic on failure from fetch. * Much refactoring see PT... * Significantly cut down on trace noise. * Bugfix: Removed extra /rvm/ in scripts path. Removed external --prefix option. * Refactored initialize out of several places into a common script and improved it's logic for handling root installs. * Bugfix: adjust rvm_prefix_path and rvm_path to be user overridable and have consistent defaults in both initialize() and install() * Applied my new found education on the naming of JRuby :) Thanks VVSiz * Minor version bump post 0.0.80 release. * Feature: 'rvm list --all' now outputs ruby strings and indicates defaults and has a few extra comments. * Support Heroku style '.gems' files. * Bugfix: rvm do actions now work with 'system' ruby. Example: 'rvm 1.9.1,system,ree rake spec' * Minor version bump after release 0.0.79. * Switch to rvm_path instead of hardcoded ~/.rvm. * Bugfix: 'rvm gems load' now works for system rubies as well. * Strip preceding whitespace. * Select 2nd field from output of sysctl. * ppc pre-empts 64 bit check. * Adjusting make_flags for PPC * Don't call make_flags for ree releases, it computes things with it's own installer. * Adjusted macruby_nightly latest url. * Bugfix: 'rvm specs/tests/rake spec/rake test' now work proper. * Bugfix: Strip off trailing 's' for specs/tests when passing to rake. * Bugfix: specs/tests CLI. * Honor user .rvmrc and /etc/rvmrc settings during rvm install. * Lop off path when collecting gem names for gemsync * Properly unset vars for rbx install and only call make_flags for 1.[8-9]* rubies. * Minor version number bump. * Remove ParseTree requirement for rbx, additionally remove %rbx gem set. * Bugfix: strip off the t for tag when checking out repo. * Bugfix: correct tag selector. * site updates. * Bugfix: add -eq 1 to test for zsh. * Disabling Installer code from rbx for now. * Added export of rvm_ruby_string and gem_set_name for selected default rubies. * Feature: Export ruby string and gem set name for extrnal scripts to take advantage of them. * Feature: Source a .rvmrc file in a directory after changing to it, if it exists. * Bugfix: Honor -C configure flags passed via command line. * Added back the --host and --build configure options. * Bugfix: (sorta) ignore calling self when $* matches completion* Minor version bump. == Release 0.0.77 * Bugfix: 'rvm gem uninstall X' no longer errors on --no-rdoc * Feature: 'rvm install ree-1.8.6' on Darwin now injects --no-tcmalloc * Removed usage of =~ for now :/ * Switched shebang lines to use /usr/bin/env. * Feature: 'rvm install curl'. (For use with curb for example: 'rvm ree ; rvm install curb -- --with-curldir=/Users/wayne/.rvm/usr/'). Thanks foca. * Minor Version Bump. * Feature: Detection of scripts directory vs rvm path. * Bugfix: 'rvm gemdir', 'rvm gemdir system', 'rvm gemdir user', etc... now all work as expected. * Bugfix: rvm 1.9.1,1.8.6 -S spec spec/hash_spec.rb. Thanks dbussink. * More tweaks to Darwin build architecture detection. * Bugfix: only honor MacOSX SDK's. Thanks rolfb. * Prevent \ interpretation. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Merge branch 'master' of github.com:wayneeseguin/rvm * Site Updates. * fixed symlink path for default-irb/default-gem * Feature: Have 'rvm use X' be verbose and output 'now using ruby X' while 'rvm X' not be verbose for scripting (by default). This can be overridden by placing rvm_verbose_flag=1 in ~/.rvmrc to always be verbose. * Feature: Cleaned up rvm list, added some color. * Bugfix: clear all gems flags when cleaning up variables. * Initial SysAdmin root level support -- specficially targeted to hosting environments. * Feature: for 'rvm gem install X' add --no-rdoc --no-ri * Bugfix: --ree-options should now actually take options. * Bugfix: i686 for x86_64 in --host and --build. * Skip autoconf step if configure is defined. * Adjust how we build llvm. * Build llvm prior to building macruby. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Buahahahahahaahahahahaha... * Fun with configure. * Switched function style in installer and utility scripts. * Improved rubygems install code some. * Bugfix: 'rvm install 1.9.2' no longer tries to install 'ppreview1' :) * Minor version bump after 0.0.73 release. == Release 0.0.73. * jruby 1.4.0 is now default. macruby now only shows up in all list if system is OSX. * Minor version bump after 0.0.72 release. * Initial jruby-head support. * space fail. * Fixed up installer based on suggestion by chrisk. * Feature: Added macruby to 'rvm list'. Adjusted VERSION to latest jeweler release (yay). * Site update. * Bugfix: ree installer now a) does not double call make_flags() and b) parses the configure to place -c before each --call. * Nice basename idea Chris Kampmeier. * Bugfix: Adjusted 'ls' in order to avoid aliases. * Make user facing message simpler. * Bugfix: adjust svn urls for new ruby string logic. * Minor version bump. == Release 0.0.71: Added macruby & rbx to rvm list. Initial (simple) ruby support. * Feature: rbx and macruby now both show up under rvm list. * rvm Release 0.0.70: Initial macruby support. * Feature: 'rvm macruby' now defaults to the 'nightly' version. * Feature: 'rvm install macruby-nightly' now works. Caution: conflicts with beta release, advise using nightly builds. * Site update. * Added initial ruby support files. * Minor version bump. * Tweaked version difference message a bit, great stuff thanks docwhat :) * Feature: Checks if rvm needs to be re-synced in the shell. * Bugfix: 'rvm gemdir' thoughts not completed are best completed. * Bugfix: Correctly check for the specification file to see if it is already installed :) * Well that was rather embarassing ... * Slowly improving gem handling logic. * Feature: respect the reported architecture of the host OS on Darwin. Additionally allow the user to override via rvm_archflags in ~/.rvmrc * Adjusted jruby download url. * jruby RC1 -> RC3 * Bugfix: We *want* shell expansion of some things :) * Bugfix: irbrc loading code, thanks yury! * Bugfix: 'rvm system' now works as expected. * Site updates. * Respect any previous configure flags. * Bugfix: Ruby now compiles more explicitely as i686 on OSX 10. * Bugfix: 'rvm gemdir' now works again, thank you Tony_. * Added extra trace output. * tyop fix. Thanks coderpath. * s/checkout/update/. Thank you rubys! * Bugfix: svn checkout is ... fascinating. * Subversion revision tweak. * Adjusted download/clone/checkout messages, thank you rubys. * Bugfix: Check for head flag for download url. * Merge branch 'master' of github.com:wayneeseguin/rvm * Bugfix: (again) 'rvm 1.9.1 --head'. Thank you rubys. * Fixed use of RUBY_ENGINE -- doesn't exist in ruby < 1.9 * Rewrote __rvm_ruby_string to be a) flexible b) handle errors better and c) far less complex! Thanks for the idea, Chrononaut! * Site update. == Release 0.0.66 * Bugfix: 'rvm 1.8.7%gemset' now works again (broken in last commit). * Bugfix: 'rvm 1.8.7-p160' now works. * Bugfix: 'rvm 1.9.1,ree,jruby benchmark some_code.rb' * Added missing file scripts/irbrc. * Moved usage out to readme. * Patches: Thank you Thomas Ritz. Altered irb files to use env vars. * Feature: Use a common irbrc for all installations for easy upgrades. * Bugfix: 'rvm 1.9.1%somegem ; gem install wirble ; rvm 1.8.7 ; rvm gems delete 1.9.1%somegem' now works properly. * Feature: IRB prompt mode is now stored in :RVM instead of :DEFAULT. * Bugfix: 'rvm gem install X' now works. * Put PAGER code back. bad monkey, careo, bad bad bad monky :-p * Site updates. * Bugfix: Do not respect the users PAGER setting as it may break rvm help. * Switch back from bash native subsitution. * Minor version bump. * Adjusted rvm debug to output information useful when debugging issues on OSX. * Added --archflags and --sdk, as well as configurable via ~/.rvmrc * Switching rbx to use the new installer. * Bugfix: Use 64 bit for SL and later, 32bit for previous. * Bugfix: tyop, thank you hsbt * Use *both* archflags for Darwin. * Bugfix: Do not rely on 'ls -t' instead use sort and tail. * Bugfix: -S and -e now work properly again. Removed --script and --execute options as they do not appear in ruby. * Move reset of configure to all variable reset. * Bugfix: 'rvm remove X' no longer tries to install after removing. Feature: 'rvm remove X' now takes a full rvm selector string. Minor version bump. * Site update, now officially publishing to gemcutter.org only. * Feature: 'rvm 1.9.1-r25443' now works. * Site update. * Upgraded ree default version. 63 commands, 384 assertions, 384 passed, 0 failed.. * Applied patch for shyouhei 'mput' ruby * Bugfix: 'rvm install 1.9.1 --rev 25443' * rvm-prompt has been rewritten to be flexible. * Bugfix: 'rvm 1.9.1-head' * Site update. * Bugfix: 'rvm install 1.9.1-head'. * Minor version bump. * Bugfix: Removed __rvm_reload * Feature: Restore cwd after rvm update. Bugfix: 'rvm update' should work again. * Minor site wording tweak. * rvm Release 0.0.62 (See PT for information). * Bugfix: properly extracting of gem names & versions * Escape paren in regex. * Logic tweak to gems loading. * Bugfix: gem name parsing for gemset laod. * Missed a spot. * Double entendre :) * Several bugfixes and features (see pT) * Site updates. * Site update. * Site Update, thank you Brian Hogan! * Bugfix: Use rvm_path and do not hardcode .rvm DOH. * Adjust to use actual architecture rather than OSX release version. * Remember kids, practice safe sed! * Date bump. * Bugfix: 1.8.* now properly use rvm's installed openssl/readline/zlib/iconv. Major accomplishment tonight, would do a backflip if I could ;) w00t * Version bump. Bugfix in btu. * Site Update. * Regex adjustment. * Switching to safer sed patterns. == Release 0.0.60: gems(et) and other bugfixes. * Bugfix: 'rvm 1.8.7-p160' works as intended. 50 tests, 351 assertions, 351 passed, 0 failed * Bugfix: install should not replace rvm-prompt location :) * Added 2 tests with assertions to cover the last feature checked in. * Bugfix: 'rvm gems X' and 'rvm gems clear' now updates the PATH properly for the new gem home. * Feature: 'rvm gems clear' now clears the current gemset, resulting to the selected ruby's default gem home. * Bugfix: If gem version is not specified, omit it. * Bugfix: Respect force flag for rvm gems load if gem is already installed. * Bugfix: rvm gems once again properly skips gems that are already installed. Feature: rvm gems load now displays red/green for success/failure of gems loading and surpresses gem's output. Added __color function. * Adding blank bundler files to site. * rvm release 0.0.59: gems(ets) * Site update. * Site documentation update, added a few more tests. * gemsets now work with the selector and multi commands, w00t! * Now have: 40 tests, 339 assertions, 339 passed, 0 failed. Gem Sets working as expected. * Feature: rvm gems completely functional! Passing test suite, w00t! * Bugfix: rvm gems load * Removed debug. * Site Update. * Site updates. * Site update. * 'rvm install ree' now works without throwing an error. * Bugfix: nasty recursive gem home bug. * Bugfix: ree string had an extra ) floating around ... * use non-prefixed less for pager default. * Updating FAQ - Textmate Workaround * So ... I can't count eh? * release 0.0.58 * Bugfix: GEM_HOME is now handled correcty. * Switched code to use preferred subshell method. * Made test clauses safer from bad input. == Release 0.0.57: Bugfixes. * Bugfix: 'rvm ruby' and 'rvm gem' with no arguments now properly issue an error message. * Bugfix: 'rvm update' now works again. * Remove debug. * Bugfix: nasty recursive gem home bug. == Release 0.0.56. 'rvm gems X', X in {<set name>, load,dump,delete,name,dir,list} * Feature(s): 'rvm gems X'. 52 tests, 443 assertions, 443 passed, 0 failed. ::grin:: w00t * Bugfix: basename: missing operand. * Fixed the tests. * BugFix: ree installer. * Use signal trap in order to cleanup when done. * Remove wget support, we're going all curl baby... * Bugfix: 'rvm --help' no longer tries to shift on an empty array. * Removed system ps1 from rvm, no longer necessary with rvm-prompt. More work on 'rvm gems ...' * Site updates. * Merge branch 'master' of github.com:wayneeseguin/rvm * Started working on the gemset ui. * Fixes issues with the display of preformatted code. * Feature: Partial string matches (for use with do actions). Added btu 0.0.1 and 29/290 tests. * Switched rbx to latest llvm compilation method (still using --jit from CLI). Renamed rvm_gem_home to rvm_ruby_gem_home for clarity. Shortened 'ruby-enterprise' to 'ree' for brevity. * Allow user to set their archflags in ~/.rvmrc. * Date update. * Minor config tweak. * Site update == Release 0.0.55: Gemset Bugfix. == Release 0.0.55: Gemset Bugfix. == Release 0.0.55: Gemset Bugfix. * Bumped 1.8.5 patchlevel to 231. * Bugfix: gemsets no longer default to version :-p * rvm Release 0.0.54: 'rvm jruby 1.4.1' (currently RC1) * Feature: 'rvm gemset delete X' * Feature: Detect curent gemset if none given and one exists. * Feature: Indicate defaults in 'rvm list --all' * Docfix: Added jruby 1.4.1 to 'rvm list --all' * Feature: 'rvm install jruby 1.4.1; rvm use jruby 1.4.0. Bugfix: Do not let the dog chase it's tail :) * Allow exact specification of gemset file during load. * Add basename extraction to test also. * Prevent users from specifying full path in gemset. * Allow --repository and --url and --repo with the CLI * Pass '--repo-url X' to override the repository url used when installing a ruby. * If you place 'rvm_ruby_repo_url' or 'rvm_jurby_repo_url' or 'rvm_rbx_repo_url' it will override rvm's urls * If you place 'rvm_ruby_repo_url' or 'rvm_jurby_repo_url' or 'rvm_rbx_repo_url' it will override rvm's urls * Show gem sources when 'rvm debug' is used. * Shift if 'use ruby' sequenece to avoid the ruby triggering do. * Summary output is now more readable. == Release 0.0.53 * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Bugfix: 'rvm benchmark increment.rb' now works with jruby. Site Updates. * Added Maz's installer patch. Added imajes rvm_loaded_flag idea. * Shortened output. * Minor version bump. * Patch: Maz, fix extraction logic after archive download. * rvm release 0.0.52: rbx fully functional. * rbx finally works fully, yay * Site modification, switch to haml (yay). * Feature: --json,--yaml only output those. Bugfix: Downloader for installs. == Release 0.0.51: ree 1.8.7 * ree 1.8.7 is now default. * Feature: ree 1.8.7. == Release 0.0.50: Progress. * Bugfix: rvm list. * Some more tweaking on macruby. * Smoothing out the installs & configuring. * using default with no default set is a warning not an error. * Bugfix: rvm reset now correctly selects system. * Minor version bump. * Bugfix: Logical switch on jruby should be and not or. * Feature: 'rvm load my.gemset' ; Feature: 'rvm dump my.gemset' * re-added install symlink. * Fixed some paths, thanks Pistos. * Merge branch 'master' of git://github.com/wayneeseguin/rvm == Release 0.0.49. * Some rubinius tweeks. * Feature: 'rvm ree 1.8.7 --head' * Indent notes. * Symlink rvm-install for next few releases to smooth upgrades. * Adding ./install * Beginning final overhaul before 0.1.0. * Feature: --trace flag to differentiate and augment from --debug flag. * Site update. * Initial try to check archives * patch the remainder of the jruby scripts * remove old scripts so that links don't lead to weird resutls * Feature: 'rvm --shebang --env inspect x,y,z' to help me help others. * Bugfix: system indicator. * Bugfix: Correctly use bin_script for rubies. THANK YOU smparkes. * Full path for shebang. * Back to symlinks. * Hardlink after install for jfiles. * hard link jfiles . * Removed extra chmod. * Silence errors we don't care about. * Set environment for jgem. * Bypass aliases for make. * use before doing. * Stick with jruby's own rubygems. * Skip rubygems and only do update for jruby. * Installer now allows for non-interactive installs. * Feature: rvm restores selected ruby after performing a multi action. Bugfix: unset rvm_ruby_selector when cleaning up variables. * Site update. * Site updates. * Bugfix: s/=true// for --enable-shared. Thanks Maz. == Release 0.0.48. Site updates. * Feature: 'rvm install/uninstall/remove X,Y,Z...' Updated usage & CLI. * Feature: 'rvm system --default' * Slowly forward with jruby... * Bugfix: rvm install X,Y * Removed stray __rvm_select * Bugfix: rvm install A,B,C now works. == Release 0.0.47: jruby + rubydo bugfixes. * jruby ::twitch:: jruby ::twitch:: ... working ... * After much mental aerobics JRuby is now working. * Bugfix: jruby shebang now properly set, yay. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Bugfix: rvm list for zsh if no rvm sourced in bashrc. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Merge branch 'master' of git@github.com:Pistos/rvm * Bugfix: /bin/bash instead of just 'bash' in case bash is not in path. == Release: 0.0.46 Essential installer and other bugfixes. * Removed pointless warnings. * Patch: For curl, detects if server does not support range command, delete archive, and retry download. Thanks Maz. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Bugfix: Ruby installs now have gem_env/path and shebang properly injected. * Bugfix: Fixed jacked up sed script, thanks Maz * Finished removing system_path items. * Feature: Clean PATH of rvm instead of storing system path. Thank you Joseph Hsu (jhsu)! * Feature: json/yaml to log/summary.json/yaml. * Bugfix: 1.9.X rubygems install. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * More cleanup. * Cleaned up visuals of rvm-install. * Bugfix: Multiple and all for rake X now work. Thank you dbussink * Single spec case working. * minor version bump. * Bugfix: Missing space around test, thanks Maz. * Bugfix: Install on use flag works now. Bugfix: existence testing and standard file testing for gem path/hme injection. * Never do things in a hurry :/ * Fix test for 1.9, thanks Maz. * Feature: Removed path from system snapshot. Bugfix: test for file in post-install. * s/sync/gemsync/g == Release 0.0.45 * JSON output reformatted and workign in zsh as well. * Bugfix: ZSH yaml fix. * Feature: 'rvm install X,Y,'Z works as intended. Bugfix: 'rvm install jruby' * Make rvm debug slightly more useful when helping people. * Bugfix: 'rvm do' === 'rvm rubydo' * Fun with popsicles. * Bugfix: gemsync actually works now. Thanks bosie. * Bugfix: gemsync :) * Added gemsync utility. Thanks bosie. * Gem Sync mege with gem dup. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Bugfix: rvm list for system, thanks Pistos/Scyllinice. Initial sync code, thanks bosie. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Silence pushes & pops, thanks darkhelmet & bosie. * rbx binary wrappers for gem and rake. == Release 0.0.44: Install Bugfix, thanks Maz. * cp -Rf / * cp -Rf :) * cp -R == Release 0.0.43. Features: 'rvm benchmark code.rb', 'rvm rake <task>' * Bugfix: 'rvm system' works again with rvm-prompt. * Bugfix: 'rvm gemdup system'. Bugfix: 'rvm gemdup user' * Unearthed gem of a gem, gem features. * gem wrapper now in place. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Added rake to rbx install. * Feature: --json Summary. * Feature: 'rvm benchmark rubyfile.rb' :). Feature: Summary as yaml 'rvm --yaml rake -T'. == Release 0.0.42. * Feature: 'rvm rake -T' (doesn't have to be just -T ;)) * * * * * * * * * * * * * * * * * * s/--enable-pthread=true/--enable-pthread/g Bugfix: patchlevel should respect 'head' and 'trunk' values. Thanks Yehuda. Feature: 'rvm remove' and 'rvm uninstall' are now split. re-enabled macruby against git head. LOL bugfix Moved VERSION.yml to lib/ Copy over lib dir on install. Install adjustment. Initial rake/gem code. Set ARCHFLAGS for Darwin. Feature: Merge configure options with user's configure options. minor version bump prepairing for next release. BugFix: Would you like a variable with that? Removed -l flag. Bugfix: patchlevel for ree. Added VERSION.yml to Rakefile, thanks tswicegood. ::twitch:: grumble... I just pushed a release :/ == Release 0.0.41: Bugfixes. Thank you community awesome. * Bugfix: rake gets installed to gem_home/bin :) * Site Updates. * Bugfix: ruby_string grep should check rev at beginning. * Remove 'j' from 'jgem' call bin script. * Bugfix: silence ls. Feature: Extracted duplicate rubydo blocks out to a function. * Silence error stream for gem list. Remove Readline comment. * Comment out manual readline build for now. * Bugfix: unset configure variable. More work on gemset loading. * Bugfix GEM_PATH. Thanks Jamie. * run bin_script after rubygems install. * version bump. * Show progress indicators for wget/curl when downloading. * Site Update. * Feature: skip already installed gem files. * Thank you Thomas Kern. Bugfix: correct gem file names for gemset load. * s/daft-wayne/wayne/g * Subshell output redirect, thanks bosie * Cleaning up cli. Updating usage. Bugfix: gemset load. * Fun with flags. * Search rvm gems cache directories for gem files before hitting the 'series of tubes'. * Bugfix: gemset load, thanks bosie. * if [ 'zsh' = 'daft' ] ; then s/parameters/configure_parameters/g * Send STDERR to /dev/null for cache check with gemset load * if [ 'zsh' = 'daft' ] ; do sed -i s/status/result/g ; done * Bugfix: Patchlevel sanity checks, thanks sfpyra. * rvm Release 0.0.40: Ruby Install Bugfix. * setn enable-shared=true * Ensure that --enable-shared is used with configure :/ == Release 0.0.39 * Only use rvm readline if it exists. * Silence Z grep * Features: ~/.bin/ruby,gem,irb,default-ruby symlinks on --default. * Bugfix: patch level. Check for non-existant url and issue error message if so. * Moved some cli related functions into rvm-cli script. * Removed --disable-shared, how'd that sneak in there :-p * Feature: gem update --system after installing 1.9.1 * Feature: rvm built in readline build support now functional. Bugfix: 1.9 installs properly w/rubygems modify instead of install. Site Updates. * Removed warning to allow people to run ruby under passenger as root ;) * Bugfix: Rubygems install for 1.9 was not honoring its test. Setting flags for readline compile. * Feature: 'rvm update --rubygems' now installs rubygems for the currently selected ruby. * Bugfix: 'rvm gemdir system user' now works. Site Updates. == Release: the .38 special. * moving forward with readline. * Doc updates, thanks anita-kun. * flash messages. * Bugfix: use 'trunk' for 'head' / 'trunk' rev. BugFix: svn update if svn repo already cloned. Feature: 'rvm install readline'. Feature: 'rvm install iconv'. * Merge branch 'master' of github.com:Pistos/rvm * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Typo fix, missing |. removed sudo from iconv install. * Added two (as of yet untested) functions. * Bugfix: rvm list now shows default ruby correctly. * 'default_' -> 'system_' * Bugfix: Only shift params if version supplied. * Feature: 'rvm update --bin'. Feature: 'rvm update --rubygems'. Bugfix: 'rvm system'. Feature: gemset load/dump extracted to functions. Feature: rubygems install extracted to function. Feature: gemset load now checks for a cached version in gem home before installing, accounts for prefix and postfix, setup for eval flag parameter later. * Initial ruby_string function, not working yet. * Bugfix: tyop :) * Feature: 'rvm update --bin.' * Bugfix: 1.9.1 gem command shebang line now proper. * Bugfix: missing dollar sign prefix. * Feature: -r|--require. Bugfix: GEM_PATH in aux scripts. Began setup of status checks for installer. * Skip rubygems for 1.9.1 * Feature: can now pass 'rvm install 1.9.1 -j 8' to have make -j8 called. Bugfix: shebang line w00t. Added GEM_PATH to aux binaries. * Feature: exit status codes propigate out of the rvm command. Feature: -S now eats to the end of the line and works as expected, example: 'rvm 1.8,1.9,jruby,rbx,ree --summary -S rake -T' * Added initial -I functionality. * equivocate arguments ending in '.rb' to -S * Added symlink rvm-install -> rvm-update * purty... * * * * * * * * * * * * * * * * * --summary now works with -S. Bugfix: 'gemdir' command actually works as intended now :) BugFix: Do not blindly adjust profiles, test for adjustment condition first. Bugfix: remove '.orig' sed backup files. Thanks Josh Peek. Now working on --summary for use with -S Merge branch 'master' of git://github.com/wayneeseguin/rvm -C should proxy to -c for rvm. Merge branch 'master' of git://github.com/wayneeseguin/rvm rvm <selector> -S <scriptname.rb> now works. Bugfix: ree now uses -C args passed in, Thanks chewie71. Bugfix: irbrc loading. Feature: use now prompts for install. Feature: Added timestamps + commands to logs. Feature: 'rvm reboot'. Cleaning up cli into functions. Merge branch 'master' of git://github.com/wayneeseguin/rvm rvm list >> multiruby -v :-p Bugfix: GEM_PATH missed a spot for system. Made version single point of change. Added GEM_PATH. Simply load, not copy user's .irbrc, thanks brainopia. Site Update, prompt. == Release 0.0.37: Bug! Bug!... Squish!!! * Made the currently selected ruby more... obvious. * Updated 'rvm list' to include a '*' in front of the currently selected ruby. * Inject blank line just before injecting source lines during install. * Bugfix: default & sytem selector now work properly. * Bugfix: rbx install. Bugfix: Check if user has unzip for jruby installs and show warning if not. Minor site updates. * Added prompt to site. * Fixed wget test, thank you Maz. * Updated site with --dump & --load * Remove debug flag. * Bugfix: gemset --dump correctly separates multiple versions now. * Bugfix: remove system *file* if it exists and is a file. * rvm-prompt works when you copy scripts/rvm-prompt to your path now :) * Feature: rvm-prompt. * Issue a warning message if rvm binaries are called as root. * Feature: ~/.rvm/default -> ~/.rvm/system ; ~/.rvm/current -> ~/.rvm/default * Bugfix: Correctly specify java/ree messages on install. * Added scripts/rvm-aliases and scripts/rvm-functions for 'extra' features. Added gemdo usage doc. Added rake to binaries list. Added initial --dump and --load for use with gemsets. * Site Updates. == Release 0.0.36 * BugFix: rubydo if interpreter is actually a ruby version number, thanks aaalex. * Fix for rubydo, all case. * Use current user path instead of default path. * Applied PATCH by Chrononaut for install to follow symlink to zshrc. * Site update. * Bumped version. * Fixed an IRBRC bug, thanks danny (dnyy). Updated site faq to advise strongly against using sudo, thanks olegshaldybin. * Bugfix: IRBRC not getting set with current. Better setting/unsetting behavior for current. * Adjusted else fork's location to be consistent with if above, thanks olegshaldybin. * Added GEM_HOME explicit setting to installer, thanks zomb. Site updates. * rvm gemdir fix. * Playing touchy-feely with some log files. * Bugfix: rvm-install not rvm-update. * Bugfix: Ensure sure that the log directory exists. * Fixed heredoc subshell for zsh :/ ;) * Bugfix: ree. Initial rakedo & gemdo, not fully baked yet. * Update now merged into installer with extra checks. Temporarily commented out actuLfile. * Removed bin/rvm-update. * Bugfix: binary install for rake. Began merging update script into the install script. * Added rbx head --jit to list --all. * rvm Release 0.0.35: * Fixed missing binaries issue with Ruby 1.9.2. * Bugfix: log file name. * Fixed db entries. * Site update. * default_system_ruby fix * Bumped 1.8.6 back to 383. * Pushed fix for syntax on Makefile line. * Added config dir so we get the db. * Renamed rvm-installer to rvm-ruby-installer. * Bugfix: missing $, thanks brainopia. Feature: Split out files. * Bugfix: Correctly unset RUBYOPT for installer if it is *non empty*. * Feature: --re-configure. Added selected variable export to prepare for install extraction. * Working on defaults from db hash store. * Site Updates. * PATH tweek for binaries. * Resorting to a semi-colon * Adding blank space to irbrc. * Bugfix: Added 'current' to selector. == Release 0.0.34: Bugfix: log_file_name... is a variable :) * Syntax check, aisle 3 * Adjusted default system checks to check if ruby is installed, thanks Maz. Bugfix: log_file_name... is a variable :) == Release 0.0.33: Bugfix: autoconf logic. * Bugfix: autoconf. * Bugfix: Correctly handle autoconf. * Site update. == Release 0.0.32: Bugfix: PATH to include user's default path now. * Adjusted binary file paths to include the user's default path. == Release 0.0.31: Feature: rvm list --all Feature: Adjusted rvm_ruby_configure. Feature: rvm update Feature: reset so that system ruby (1.8) is used to build rubinius, which requires parsetree. Thanks manveru. Feature: env/path injection to executables. Feature: Added wget support. Feature: rvm_run function. Added update --head. Bugfix: Exit out of push'd directory when encountering a failure. Bugfix: Made trimming the last : in the path more shell agnostic. Bugfix: Moved logs outside eval. Thank you metaskills. Bugfix: Adjusted default configure options. Updated some site docs. Thanks mr-interweb. Bugfix: don't shift on use if 2nd parameter is empty thanks mr-interweb. * Feature: rvm list --all * Bugfix: Exit out of push'd directory when encountering a failure. * Added wget support. * Made trimming the last : in the path more shell agnostic. * Added rvm-run function. Added update --head. * Moved logs outside eval. * Trying something with the configure line for metaskills. * Adjusted default configure options. Updated some site docs. Thanks mr-interweb. * Bugfix, don't shift on use if 2nd parameter is empty thanks mr-interweb. * Adjusted rvm_ruby_configure. * Added 'rvm update' feature. * Many variable renames/replacements for line shortening and readability. * Added reset so that system ruby (1.8) is used to build rubinius, which requires parsetree. Thanks manveru. * Added reset for rubinius which requires 1.8 to install due to parsetree, thanks manveru. * Working env/path injection. * Applying patch from ujihisa: Fixed installer's behavior. See the details below. * Moved svn url block inside the svn if. == Release 0.0.30 Feature: 1.8.6-p383 is now default. Feature: --set-prompt option for prepending ruby version to prompt (opt-in). Feature: GEM_HOME/PATH to: gem, irb, erb, ri, rdoc, testrb, rake. Feature: install --force option Feature: git support to ruby-install-source. Bugfix: unset variables in default file if not set by default. Feature: rvm_prompt added to defaults file. Bugfix: Path fix. Feature: Ruby Wrapper Script. Bugfix: Log path error messages. Typos in docs. Bugfix: usage to be more clear for --configure option, thanks mikeg1a. Feature: alias '--trace' for '--debug' for rake lovers :) * Update 1.8.6 to use 383 as default. * Added --set-prompt option for prepending ruby version to prompt (opt-in). * Added GEM_HOME/PATH to: gem, irb, erb, ri, rdoc, testrb, rake. * Added GEM_HOME to rake binary now. * Added --force option for install. * Added git support to ruby-install-source. Bugfix: unset variables in default file if not set by default. * Adding rvm_prompt to defaults file. * Path fix. Ruby Wrapper Script. * Working out the make & make install options for macruby. * *actually* fixed the log path error messages. * Fixed quoting issue. * Fixed rvm_ruby_repo_url for macruby. * Fixed url for macruby in info. * Fixed url for macruby * Typo fixes for docs. Working on MacRuby with help from lukeredpath. * Updated usage to be more clear for --configure option, thanks mikeg1a. Added alias '--trace' for '--debug' for rake lovers :) == Release 0.0.29: rvm Passenger Support. (with a gemspec :) == Release 0.0.29: rvm Passenger Support. * Bugfix for $@ with passenger, thanks lukeredpath. * Added Passenger Support. Bugfix for error log location notification during installs. == Release 0.0.28: Reverted installation bin scripts. Two bug fixes. * Bugfix for '--configure' thanks Scyllinice * Updated site. * Updated website. * Added unset of rvm_prompt on reset, thanks zmack * Reverted the bin/rvm-* scripts to their previous state. == Release 0.0.27 Feature 'rvm implode' Feature --jit flag to tell Rubinius to build with JIT (RBX_LLVM=1). Bugfix reset should select system only after doing some cleanup. Feature missing variable namespaces Feature exits when install goes badly. Feature for use with PS1 Feature support for inclusion of user's irbrc, if it exists. * Added 'rvm implode' * Webssite Update. * Added --jit flag to tell Rubinius to build with JIT (RBX_LLVM=1). * Reset should select system only after doing some cleanup. * Added missing variable namespaces * Adding exits when install goes badly. * Don't unset rvm_prompt * Tweaked user's irbrc inclusion to be more efficient (no variable). * Added support for inclusion of user's irbrc, if it exists. == Release 0.0.26: Several bugfixes. 'rvm default' now uses the current set default or system. 'rvm system' now uses system. Adjusted namespace to be even more discreet. Added rbx for rubinius. Cleaned up usage. Removed install all feature. Made rvm_prompt opt-in via env variable. * Gem install/update tweak. Updated setdefault docs page. * 'rvm default' now uses the current set default or system. 'rvm system' now uses system. Added bugfix for install/update, thanks Maz. * Adjusted namespace to be even more discreet. Updated site docs some more. * Add rbx. Adjusted usage. * Trimmed down 'rvm usage' some. You don't need an 'Installation' section if you are using 'rvm usage' ;) * Bumped version #'s and updated date. Removed usage for install all. * Now exporting 'rvm_prompt' env var for use with prompts, use if you like. * Make prompt feature 'opt-in' :) * Removing 'install all' feature. * Third time is a charm? :) * Another bugfix for install all, thanks Peter Cooper. * Bugfix for install all, thanks Peter Cooper. * Tweaked install all. Updated site docs some. * Merge branch 'master' of git://github.com/wayneeseguin/rvm == Release 0.0.25. 'Major Nerdon' * jruby HEAD working. * Finished initial revision of rubydo. * Added an extra line to the output. * Path now updates to display currently selected ruby version. Small bugfix in update thanks to Maz. * Simplifying install & update. Added message for MacRuby. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Added defatults cache file. Added rvm-cache for string storage (defaults). Added ability for more than one --configure option :). More progress with macruby. Initial Rubinius support. Updated Thanks. Initial macruby code, had to stop testing because I could not get macruby compiling :) Named releases, named svn tags, svn revisions, svn head for 1.[8-9].X. Initial tag usage functional, thank you Kirk Haines. Bugfix: install all should not try to install 'REE 1.3.1' :), thank you Scyllinice. Initial tag code. Bugfix for ree: add --no-tcmalloc to install, thank you r38y Added abillity to remove a named gem set. Remove gem directories for versions on uninstall. Added gem set support. Bugfix in install script. Thank you ddfreyne. Fix to install script, thanks Tsykoduk Bugfix, odd typo. Cleaning up code. Fixed ree (again :) IRB Support complete. Added individual ruby IRBRC support. Shuffled around directories so that things are closer to their final form early on. Merge branch 'master' of git://github.com/wayneeseguin/rvm Merge branch 'master' of git://github.com/wayneeseguin/rvm Fixed: -h | --help | rvm usage | rvm help Fixed rvm info. Merged with rvm debug secion. Improved rvm debug output. Namespaced niceness to rvm_niceness. Namespaced configure to rvm_ruby_configure Added patch by Jim Lindley on how to 'install from source'. You must export what you wish to use :) Merge branch 'master' of git://github.com/wayneeseguin/rvm Change test for rvm source file to also check if greater than zero. Merge branch 'master' of git://github.com/wayneeseguin/rvm No longer using -f check with curl since we are using the -C - flags. Slightly improve error handling. Merge branch 'master' of git://github.com/wayneeseguin/rvm Merge branch 'master' of git://github.com/wayneeseguin/rvm Merge branch 'master' of git://github.com/wayneeseguin/rvm We are (generally) not psychic, have curl automatically determine where to continue downloading. Merge branch 'master' of git://github.com/wayneeseguin/rvm Enable 'continue partial downloads' for curl, thanks Pistos\! Merge branch 'master' of git://github.com/wayneeseguin/rvm Adjust rvm_{major,minor} version extraction to play nice with zsh... Running a ruby file against all versions of ruby or just one now works. Fixed ree install. Site updates. Merge branch 'master' of git://github.com/wayneeseguin/rvm Merge branch 'master' of git@github.com:Pistos/rvm Updated thank you's on site. Adjusted path cleaning to remove trailing : Refactoring complete. Testing needed. Removed switching message now that we stay in the same shell. Repaying technical debt. Refactoring. Merge branch 'master' of git://github.com/wayneeseguin/rvm 'ls' is now referencing '/bin/ls' to avoid potential alias issues, thanks Pistos!!!. Make the about information show up again in the usage :) Shortened usage and made it more maintainable at the same time, yay Merge branch 'master' of git://github.com/wayneeseguin/rvm More cleaning up, namespacing, working on support for 1.8.X Merge branch 'master' of git://github.com/wayneeseguin/rvm Added awesome sed-fu patch by Chrononaut. == Release 0.0.24: Quick, hide before she sees! == Release 0.0.23: It works! * Completely separated out rvm's gems from system 1.8. * Added support for bin_path. * ree now works with it's own rubygems again. Seeing some oddities with 1.9.2. * Namespaced log_path. Rubygems now good for 1.8.X, still failing for ree. * Default variable bugfix. All ruby installs work. Rubygems install needs bugfix (gem isn't going to the correct location). * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Rename default_gem_path to default_user_gem_path * More namespacing. * Began the variable namespacing process. * Add rvm reload option. * Adjusted install & update based on feedback from Maz on IRC. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Download file check based on archive path. * Fixed prefix path checking and logic. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Merge branch 'master-upstream' * Defaulting log path properly to install_path/log * Changed variable defaults to use :- instead of simply -. * Added patch for archives, thanks to Pistos. * Applied niceness patch by Pistos. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * Removed pwd for install & update. Added /log to log path. Thanks Maz. * Removed lots of trailing whitespace for Pistos. * Bugfix for zsh in rvm-install. Abstracted log dir. * Merge branch 'master' of git://github.com/wayneeseguin/rvm * ~/.rvm/log. Hook into .bashrc also. Install all bugfix. Install script capability testing cleanup. * Merge branch 'zsh' * Merge branch 'english-changes' * Merge branch 'master' of git://github.com/wayneeseguin/rvm == Release 0.0.22: Let it Snow Leopards * Merge commit 'a8e55b29195f15b773dd698beb236493f372efdd'; branch 'site' * Credit Pistos, add patch by Caius Durling. * Merge branch 'master' into site == Release 0.0.21. Is there a cure for stupidity? == Release 0.0.20. Bugfix: zsh using curl. Bugfix: REE Uninstall. * Fixed ree uninstall bug. * 'Ignore built gems.' -- Pistos * 'Added evals to calls, to satisfy zsh' -- Pistos * Added evals to $curl calls, to satisfy zsh. * Merge branch 'master' of git@github.com:Pistos/rvm * freenod -> freenode * Ignore built gems. * Added rvm symlinks to generate ~/.rvm/bin/ binary symlinks. Fixed RUBYOPT 'bug' when installing ree. * Added rvm symlinks * Fixed documentation error in the installer. * Updated Site. * Updated README and website to https://rvm.io/ * Latest site. * Website initial just about ready. * Unset GEM_HOME and MY_RUBY_HOME on default switch. * gemdup getting there... == Release 0.0.18. * Adjusted rvm debug. * Parital gemdup functionality (default & system). * Added system default ruby to rvm list. * rvm reset now works proper for hard system reset. * Adding rvm-update. * Added rvm reset feature. == Release 0.0.16. Many documentation typo fixes. Added Install section to usage. Added more thank you's. Added curl detection (for Ubuntu). Added force to symlinks. Fixed gemdir system/user. Added both shells option to install. Improved wording of rvm-install script. * Bugfix on source pat. * Installer now prompts for manual install and is much more forthcoming and helpful. == Release 0.0.14. Bitten by RubyGems. == Release 0.0.13. Bugfix in mkdir for source dirs. * Namespaced logging functions. * Refined debug. == Release 0.0.11. rvm gemdir functional. * Updated Readme. * rvm gemdir now functions. == Release 0.0.10. rvm default and switching now work properly with the path. Began prepairing for abstraction. * Label gemdup TODO * Updated README * Added rvm list. * Updated README * Uninstall now works. * Added sanity check for rvm-install to deny installation as root. == Release 0.0.8 * Debug switch now works. Added root sanity check. == Release 0.0.7 * Addded gemdup example. Fixed a rather embarassing typo. == Release 0.0.6 * Installations are now verbose and clean. REE now works properly. rvm -v|--version alone now displays the version of rvm. * Updated usage & readme. * When not specifying implementation and version, set to default. * Added Credits & Website * Added version and author line and updated wording for usage/docs. Removed rubinius plans for now. * Don't depend on uninstall. * Added default task => :gem * Updated rake gem * Added initial zsh support. * un-DRY curl. * Properly namespace all rvm functions with rvm-. * Added 1.9.2 support. Added per interpreter rubygems install (for source installs). * Added --configure option override. Fixed a typo. * Typo fix. Merged two variables that were the same except in name. * gemdir and srcdir now work as advertised. * Improved usage documentation. Removed path, rvm-setup, leopard (redundant to default). * Added debug action. Added all install. Added RVM module place holder. Removed package manager option, this should be for system default control. * Added LICENCE file to gem build. * Fixed executable permissions for jruby. * Prepairing for first release. * gemdup stil needs some love but we're good to go. * About to refactor. * Correctly refer to the bash/rvm-setup script for setup option. * Added LICENCE File. * Adjusted the rvm command so that it does not hijack the cwd. * Initial Gem version. * Switched source and package to simply prefix. * Updated path order and installer. * Added Installer. * Initial rvm, ruby, jruby, leopard functional. 1.11. Rakefile #!/usr/bin/env ruby require "rubygems" # # VirtualBox Helpers # # Matches a host declaration in a ssh config file. HOST_REGEXP = /^\s*Host\s+([^\s#*]+)/ SNAPSHOT = (ENV['SNAPSHOT'] || 'CURRENT').upcase SSH_CONFIG_FILE = ENV['SSH_CONFIG_FILE'] || File.expand_path('../config/ssh', __FILE__) def shell(cmd) puts "$ #{cmd}" system(cmd) end def hosts @hosts ||= begin hosts = [] File.open(SSH_CONFIG_FILE) do |io| io.each_line do |line| next unless line =~ HOST_REGEXP hosts << $1 end end hosts end end namespace :vbox do desc "start each vm" task :start => :stop do hosts.each do |host| shell "VBoxManage -q snapshot #{host} restore #{SNAPSHOT}" shell "VBoxManage -q startvm #{host} --type headless" shell "ssh -MNf -F '#{SSH_CONFIG_FILE}' '#{host}' >/dev/null 2>&1 </dev/null" end end desc "stop each vm" task :stop do hosts.each do |host| if `VBoxManage -q list runningvms`.include?(host) shell "VBoxManage -q controlvm #{host} poweroff" end end end desc 'Run the tests remotely on each VM' task :test do begin Rake::Task["vbox:start"].invoke Rake::Task["vbox:remote_test"].invoke ensure Rake::Task["vbox:stop"].execute(nil) end end desc 'Run the tests remotely (assuming each VM is running)' task :remote_test do local_dir = File.expand_path("..", __FILE__) remote_dir = "$(pwd)/rvm" remote_script = "vboxtest/test_suite.sh" sh "'#{File.expand_path("../vboxtest.sh", __FILE__)}' -L '#{local_dir}' -R '#{remote_dir}' -S '#{remote_script}' #{hosts.join(' ')}" end desc 'Run the tests locally' task :local_test do sh File.expand_path("../vboxtest/test_suite.sh", __FILE__) end end 1.12. README {master:<img src="https://secure.travis-ci.org/wayneeseguin/rvm.png?branch=master" alt="Build Status" /> stable:<img src="https://secure.travis-ci.org/wayneeseguin/rvm.png?branch=stable" alt="Build Status" />}[http://travisci.org/#!/wayneeseguin/rvm/branch_summary] = rvm * https://rvm.io/ * https://github.com/wayneeseguin/rvm/ == DESCRIPTION: RVM is the Ruby enVironment Manager (rvm). It manages Ruby application environments and switching between them. == Installation curl -L get.rvm.io | bash -s stable [--ruby] [--rails] [--trace] stable :: Install stable RVM, good for servers. --ruby :: Additionally install latest ruby version (MRI). --rails :: Install gem rails into default gemset (also installs ruby if not selected). --trace :: Print trace of the installation, gist output when you have problems. More details here: https://rvm.io/rvm/install/ == Usage rvm [Flags] [Options] Action [Implementation[,Implementation[,...]] == Flags --default --debug --trace --force --summary --latest --gems --docs --reconfigure --skip-gemsets :: :: :: :: :: :: :: :: :: :: with 'rvm use X', sets the default ruby for new shells to X. Toggle debug mode on for very verbose output. Toggle trace mode on to see EVERYTHING rvm is doing. Force install, removes old install & source before install. Used with rubydo to print out a summary of the commands run. with gemset --dump skips version strings for latest gem. with uninstall/remove removes gems with the interpreter. with install, attempt to generate ri after installation. Force ./configure on install even if Makefile already exists. with install, skip the installation of default gemsets. == Options -v|--version -l|--level --bin -S -e --gems :: :: :: :: :: :: Emit rvm version loaded for current shell patch level to use with rvm use / install path for binaries to be placed (~/.rvm/bin/) Specify a script file to attempt to load and run (rubydo) Execute code from the command line. Used to set the 'gems_flag', use with 'remove' to remove gems :: Used to set the 'archive_flag', use with 'remove' to remove archive :: With MRI Rubies you may specify one or more full paths to patches --archive --patch for multiple, specify comma separated: --patch /.../.../a.patch[%prefix],/.../.../.../b.patch -C|--configure 'prefix' is an optional argument, which will be bypassed to the '-p' argument of the 'patch' command. It is separated from patch file name with '%' symbol. :: custom configure options. If you need to pass several configure options then append them comma separated: -C --...,--...,--... --nice --ree-options --with-rubies :: process niceness (for slow computers, default 0) :: Options passed directly to ree's './installer' on the command line. :: Specifies a string for rvm to attempt to expand for set operations. == Action (Note: for most actions, 'rvm help action-name' may provide more information.) *usage* version use reload implode :: :: :: :: :: show this usage information show the rvm version installed in rvm_path setup current shell to use a specific ruby version reload rvm source itself (useful after changing rvm source) (seppuku) removes the rvm installation completely. This means everything in $rvm_path (~/.rvm || /usr/local/rvm). This does not touch your profiles. However, this means that you must manually clean up your profiles and remove the lines which source RVM. get :: {head,stable} upgrades rvm to latest head or stable version. Check 'rvm help get' for more details. reset (If you experience bugs try this first with head version, then ask for help in #rvm on irc.freenode.net and hang around) :: remove current and stored default & system settings. debug (If you experience odd behavior try this second) :: show the *current* environment information for current ruby :: print the *current* ruby version and the name of any gemset being used. :: show info plus additional information for common issues install :: install one or many ruby versions uninstall remove See also: https://rvm.io/rubies/installing/ :: uninstall one or many ruby versions, leaves their sources :: uninstall one or many ruby versions and remove their sources info current migrate upgrade :: Lets you migrate all gemsets from one ruby to another. :: Lets you upgrade from one version of a ruby to another, including migrating your gemsets semi-automatically. wrapper :: generates a set of wrapper executables for a given ruby with the specified ruby and gemset combination. Used under the hood for passenger support and the like. cleanup :: Lets you remove stale source folders / archives and other miscellaneous data associated with rvm. :: Lets you repair parts of your environment e.g. wrappers, env files and and similar files (e.g. general maintenance). :: Lets your backup / restore an rvm installation in a lightweight manner. repair snapshot disk-usage tools docs rvmrc :: Tells you how much disk space rvm install is using. :: Provides general information about the ruby environment, primarily useful when scripting rvm. :: Tools to make installing ri and rdoc documentation easier. :: Tools related to managing rvmrc trust and loading. do tests specs monitor :: :: :: :: gemset :: gemsets: https://rvm.io/gemsets/ rubygems :: Switches the installed version of rubygems for the current ruby. gemdir srcdir :: display the path to the current gem directory (GEM_HOME). :: display the path to rvm source directory (may be yanked) fetch list :: Performs an archive / src fetch only of the selected ruby. :: show currently installed rubies, interactive output. pkg https://rvm.io/rubies/list/ :: Install a dependency package {readline,iconv,zlib,openssl} notes https://rvm.io/packages/ :: Display notes, with operating system specifics. runs an arbitrary command against specified and/or all rubies runs 'rake test' across selected ruby versions runs 'rake spec' across selected ruby versions Monitor cwd for testing, run `rake {spec,test}` on changes. export :: Temporarily set an environment variable in the current shell. unexport :: Undo changes made to the environment by 'rvm export'. requirements :: Shows additional OS specific dependencies/requirements for building various rubies. == Implementation *ruby* jruby rbx ree :: :: :: :: macruby maglev ironruby system default :: :: :: :: :: MRI/YARV Ruby (The Gold Standard) {1.8.6,1.8.7,1.9.1,1.9.2...} JRuby, Ruby interpreter on the Java Virtual Machine. Rubinius Ruby Enterprise Edition, MRI Ruby with several custom patches for performance, stability, and memory. MacRuby, insanely fast, can make real apps (Mac OS X Only). GemStone Ruby, awesome persistent ruby object store. IronRuby, NOT supported yet. Looking for volunteers to help. use the system ruby (eg. pre-rvm state) use rvm set default ruby and system if it hasn't been set. https://rvm.io/rubies/default/ == Resources: https://rvm.io/ https://www.pivotaltracker.com/projects/26822 == Contributions: Any and all contributions offered in any form, past present or future, to the RVM project are understood to be in complete agreement and acceptance with the Apache Licence v2.0. == LICENSE: Copyright (c) 2009-2011 Wayne E. Seguin Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 1.13. .gitignore gems/ *.gem site/.sass-cache/ site/tmp/dependencies/ site/tmp/ tags .*.swp tmp/ *.rbc pkg/ .rvmrc .DS_Store .idea aclocal.m4 autom4te.cache/ config.status configure install-sh Makefile depcomp missing .deps/ README.rdoc install.sh config/ssh db/config.yml config/database.yml test/rvm_test_suite/ruby/config/database.yml test/rvm_test_suite/ruby/db/config.yml test/rvm_test_suite/ruby/db/*.sqlite 1.14. vboxtest.sh #! /bin/sh ############################################################################ ssh_config_file=${SSH_CONFIG_FILE:-config/ssh} local_dir=${LOCAL_DIR:-$(pwd)/test} remote_dir=${REMOTE_DIR:-\$(pwd)/$(basename "$local_dir")} remote_script=${REMOTE_SCRIPT:-test_suite.sh} usage="usage: %s [-F SSH_CONFIG_FILE] [-L LOCAL_DIR] [-R REMOTE_DIR] [-S SCRIPT] [-h] HOSTS...\n" option=" %s %s\n" while getopts "F:G:L:R:S:h" opt do case $opt in F ) ssh_config_file=$OPTARG ;; L ) local_dir=$OPTARG ;; R ) remote_dir=$OPTARG ;; S ) remote_script=$OPTARG ;; h ) printf "$usage" $0 printf "$option" "-F" "the ssh config file" printf "$option" "-L" "the local dir" printf "$option" "-R" "the remote dir" printf "$option" "-S" "the remote script" printf "$option" "-h" "prints this help" exit 0 ;; \? ) printf "$usage" $0 exit 2 ;; esac done shift $(($OPTIND - 1)) ############################################################################ # # transfer tests # for host in "$@" do ssh -q -T -F "$ssh_config_file" "$host" -- <<SCRIPT rm -rf "$remote_dir" if [ "\$(dirname "$remote_dir")" != "" ] then mkdir -p "\$(dirname "$remote_dir")" fi SCRIPT scp -q -r -p -F "$ssh_config_file" "$local_dir" "$host:$remote_dir" status=$? if [ $status -ne 0 ] then echo "[$status] could not scp tests to host: $host" >&2 exit 1 fi done # # run tests # for host in "$@" do echo "############## $host ##############" ssh -q -F "$ssh_config_file" "$host" -- "$remote_dir/$remote_script" </dev/null status=$? if [ $status -ne 0 ] then echo "[$status] $remote_dir/$remote_script" >&2 exit 1 fi done ############################################################################ 1.15. binscripts 1.15.1. rvm-smile #!/usr/bin/env bash printf "%b" " | | .:::. | .... ::::: | ,;' .;: :: ..: \`:::' | ::. ..:,:;.,:;. . :: .::::. \`:' | '''::, :: :: :: \`:: :: ;: .:: : | ,:'; ::; :: :: :: :: :: ::,::''. . | \`:,,,,;;' ,;; ,;;, ;;, ,;;, ,;;, \`:,,,,:' :;: " ..::''''::.. .;'' \`\`;. :: :: :: :: :: :: :: :: :: .:' :: :: \`:. :: :: : : :: :: \`:. .:' :: \`;..\`\`::::''..;' 1.15.2. rvm-shell #!/usr/bin/env bash export HOME="${HOME%%+(\/)}" # Remove trailing slashes if they exist on HOME if (( ${rvm_ignore_rvmrc:=0} == 0 )) then for rvmrc in /etc/rvmrc "$HOME/.rvmrc" do if [[ -f "$rvmrc" ]] then if GREP_OPTIONS="" \grep '^\s*rvm .*$' "$rvmrc" >/dev/null 2>&1 then printf "%b" "\nError: $rvmrc is for rvm settings only.\nrvm CLI may NOT be called from within $rvmrc. \nSkipping the loading of $rvmrc" return 1 else source "$rvmrc" fi fi done fi export rvm_path if [[ -z "${rvm_path:-}" ]] then if (( UID == 0 )) && [[ -d "/usr/local/rvm" ]] then rvm_path="/usr/local/rvm" elif [[ -d "${HOME}/.rvm" ]] then rvm_path="${HOME}/.rvm" elif [[ -d "/usr/local/rvm" ]] then rvm_path="/usr/local/rvm" else echo "Can't find rvm install!" 1>&2 ; exit 1 fi fi true ${rvm_scripts_path:="$rvm_path/scripts"} __rvm_shell_lookup_script() { local relative_scripts_dir directory if [[ -L $0 ]] then relative_scripts_dir="$(dirname -- "$(dirname -- "$( readlink "$0")" )" )/scripts" #" else relative_scripts_dir="$(dirname -- "$(dirname -- "$0")")/scripts" #" fi for directory in "$rvm_scripts_path" "$HOME/.rvm/scripts" "/usr/local/rvm/scripts" "$relative_scripts_dir" do if [[ -d "$directory" && -s "$directory/rvm" ]] then echo "$directory/rvm" return fi done } case $0 in (*-rvm-env) selected_shell=${0%-rvm-env} ;; (*) selected_shell=bash ;; esac selected_shell="$(basename "${selected_shell}")" if [[ -n "$1" && ! -f "$1" && -n "$(echo "$1" | GREP_OPTIONS="" \grep -v '^-')" ]] then rvm_shell_ruby_string="$1" shift elif [[ "$1" == "--path" && "$2" =~ /* ]] then if [[ -d "$2" ]] then cd $2 else rvm_shell_ruby_string="default" fi shift 2 fi rvm_shell_rvm_path="$(__rvm_shell_lookup_script)" if [[ -n "$rvm_shell_rvm_path" ]] then source "$rvm_shell_rvm_path" # Setup as expected. if [[ -n "$rvm_shell_ruby_string" ]] then if ! rvm "$rvm_shell_ruby_string" then echo "Error: RVM was unable to use '$rvm_shell_ruby_string'" 1>&2 exit 1 fi else rvm rvmrc load >/dev/null 2>&1 fi fi exec ${selected_shell} "$@" 1.15.3. rvm #!/usr/bin/env bash if (( ${rvm_ignore_rvmrc:=0} == 0 )) then declare rvmrc rvm_rvmrc_files=("/etc/rvmrc" "$HOME/.rvmrc") if [[ -n "${rvm_prefix:-}" ]] && ! [[ "$HOME/.rvmrc" -ef "${rvm_prefix}/.rvmrc" ]] then rvm_rvmrc_files+=( "${rvm_prefix}/.rvmrc" ) fi for rvmrc in "${rvm_rvmrc_files[@]}" do if [[ -f "$rvmrc" ]] then if GREP_OPTIONS="" \grep '^\s*rvm .*$' "$rvmrc" >/dev/null 2>&1 then printf "%b" " Error: $rvmrc is for rvm settings only. rvm CLI may NOT be called from within $rvmrc. Skipping the loading of $rvmrc " exit 1 else source "$rvmrc" fi fi done unset rvm_rvmrc_files unset rvmrc fi export rvm_path if [[ -z "${rvm_path:-}" ]] then if (( UID == 0 )) && [[ -d "/usr/local/rvm" ]] then rvm_path="/usr/local/rvm" elif [[ -d "${HOME}/.rvm" ]] then rvm_path="${HOME}/.rvm" elif [[ -d "/usr/local/rvm" ]] then rvm_path="/usr/local/rvm" else echo "Can't find rvm install!" 1>&2 ; exit 1 fi fi # allow disabling check temporary : rvm_is_not_a_shell_function:${rvm_is_not_a_shell_function:=1} # if to prevent fork-bomb if source "${rvm_scripts_path:="$rvm_path/scripts"}/rvm" then rvm "$@" else echo "Error sourcing RVM!" 1>&2 exit 1 fi 1.15.4. rvmsudo #!/usr/bin/env bash sudo_args=() while [[ $# -gt 0 ]] ; do token="${1}" #rvm trace flag case "${token}" in (--trace) export PS4="+ \${BASH_SOURCE##\${rvm_path:-}} : \${FUNCNAME[0]:+\${FUNCNAME[0]}()} set -o xtrace ;; \${LINENO} > " #rvm verbose flag (--verbose) set -o verbose ;; #not an rvm option, treat as sudo option (-*) sudo_args+=("$token") #option with value case "$token" in (-g|-u|-p|-r|-t|-U|-C) shift #read & append the value sudo_args+=("$1") ;; esac ;; #no more options skip processing (*) break ;; esac #go to next param shift done if [[ $# -gt 0 ]] then eval command sudo \"\${sudo_args[@]}\" /usr/bin/env $(/usr/bin/env | GREP_OPTIONS="" \grep -E '^rvm|^gemset|^http_|^PATH|^IRBRC|RUBY|GEM' | sed 's/=\(.*\)$/="\1"/' ) \"\$@\" else printf "%b" "Usage:\n $0 [--trace] [--verbose] [sudo-options] command [command-options]\n" fi 1.15.5. rvm-exec #!/usr/bin/env bash export HOME="${HOME%%+(\/)}" # Remove trailing slashes if they exist on HOME if (( ${rvm_ignore_rvmrc:=0} == 0 )) then for rvmrc in /etc/rvmrc "$HOME/.rvmrc" do if [[ -f "$rvmrc" ]] then if GREP_OPTIONS="" \grep '^\s*rvm .*$' "$rvmrc" >/dev/null 2>&1 then printf "%b" "\n Error: $rvmrc is for rvm settings only. rvm CLI may NOT be called from within $rvmrc. Skipping the loading of $rvmrc " exit 1 else source "$rvmrc" fi fi done fi export rvm_path if [[ -z "${rvm_path:-}" ]] then if (( UID == 0 )) && [[ -d "/usr/local/rvm" ]] then rvm_path="/usr/local/rvm" elif [[ -d "${HOME}/.rvm" ]] then rvm_path="${HOME}/.rvm" elif [[ -d "/usr/local/rvm" ]] then rvm_path="/usr/local/rvm" else echo "Can't find rvm install!" 1>&2 ; exit 1 fi fi true ${rvm_scripts_path:="$rvm_path/scripts"} __rvm_shell_lookup_script() { local relative_scripts_dir relative_scripts_dir="$(dirname -- "$(dirname -- "$0")")/scripts" for directory in "$rvm_scripts_path" "$HOME/.rvm/scripts" "/usr/local/rvm/scripts" "$relative_scripts_dir"; do if [[ -d "$directory" && -s "$directory/rvm" ]]; then echo "$directory/rvm" return fi done } if [[ -n "$1" && ! -f "$1" && -n "$(echo "$1" | GREP_OPTIONS="" \grep -v '^-')" ]]; then rvm_shell_ruby_string="$1" shift fi rvm_shell_rvm_path="$(__rvm_shell_lookup_script)" if [[ -n "$rvm_shell_rvm_path" ]]; then source "$rvm_shell_rvm_path" # Setup as expected. if [[ -n "$rvm_shell_ruby_string" ]]; then rvm "$rvm_shell_ruby_string" if [[ "$?" -gt 0 ]]; then echo "Error: RVM was unable to use '$rvm_shell_ruby_string'" 1>&2 exit 1 fi else rvm rvmrc load >/dev/null 2>&1 fi fi exec "$@" 1.15.6. rvm-prompt #!/usr/bin/env bash add() { token=${1:-""} eval "${token}_flag=1" ; shift if [[ -n "$format" ]] ; then [[ ${previous_is_format_var:-0} == 1 ]] && eval "${token}_prefix_flag=1" format="${format}\$${token}" else format="\$${token}" fi previous_is_format_var=1 return 0 } add_raw_token() { previous_is_format_var=0 token=${1:-""} format="${format:-""}${token}" return 0 } rvm_gemset_separator="${rvm_gemset_separator:-"@"}" ruby=$( builtin command -v ruby | GREP_OPTIONS="" \grep -v $rvm_path/bin/ruby ) if [[ -n "$ruby" && -n "$(echo "$ruby" | awk '/rvm/{print}')" ]] ; then unset format while [[ $# -gt 0 ]] ; do token="$1" ; shift case "$token" in i|interpreter) add "interpreter" ;; v|version) add "version" ;; p|patchlevel) add "patchlevel" ;; r|revision) add "revision" ;; a|architecture) add "architecture" ;; g|gemset) add "gemset" ;; u|unicode) add "unicode" ;; s|system) ;; #skip when in ruby -d|--no-default) no_default=1 ;; *) add_raw_token "$token" ;; esac done if [[ -z "${format:-""}" ]] ; then for default in interpreter version patchlevel gemset ; do add "$default" done fi ruby_string=$(dirname "$ruby" | xargs dirname | xargs basename) if [[ -n "$no_default" ]]; then # Do not display anything if no default flag was provided # and we are using the default ruby # Only people who explicitely ask for this will have the # slight performance penalty associated. if [[ "$(rvm tools identifier)" == "$(rvm alias show default)" ]] ; then exit 0 fi fi strings=(${ruby_string//-/ }) if [[ ${interpreter_flag:-0} -gt 0 || -n "$unicode_flag" ]] ; then interpreter=${strings[0]} [[ ${interpreter_prefix_flag:-0} -gt 0 ]] && interpreter="-${interpreter}" fi if [[ ${version_flag:-0} -gt 0 || -n "$unicode_flag" ]] ; then version=${strings[1]} [[ ${version_prefix_flag:-0} -gt 0 ]] && version="-${version}" fi if [[ ${#strings[@]} -gt 2 ]] ; then if [[ ${patchlevel_flag:-0} -gt 0 ]] ; then patchlevel=${strings[2]} [[ ${patchlevel_prefix_flag:-0} -gt 0 ]] && patchlevel="-${patchlevel}" fi fi if [[ ${architecture_flag:-0} -gt 0 ]] ; then architecture="$(echo "$(ruby -v)" | sed 's/^.*\[//' | sed 's/\].*$//')" [[ ${architecture_prefix_flag:-0} -gt 0 ]] && architecture="-${architecture}" fi if [[ ${gemset_flag:-0} -gt 0 ]] ; then case "${GEM_HOME:-""}" in *${rvm_gemset_separator:-"@"}*) gemset="${rvm_gemset_separator:-"@"}${GEM_HOME/*${rvm_gemset_separator:-"@"}/}" ;; esac fi if [[ ${unicode_flag:-0} -gt 0 ]] ; then case "$interpreter" in jruby) unicode="" ;; rbx) unicode="❖" ;; ree) unicode="" ;; macruby) unicode="" ;; maglev) unicode="㎖" ;; ironruby) unicode="♭" ;; system) unicode="" ;; goruby) unicode="";; ruby) case ${version:-""} in 1.8.6) unicode="❻" ;; 1.8.7) unicode="❼" ;; 1.8*) unicode="" 1.9.1) unicode="❶" ;; ;; 1.9.2) unicode="❷" ;; 1.9.3) unicode="❸" ;; *) unicode="" ;; esac ;; *) unicode="" ;; esac if echo "$ruby_string" | GREP_OPTIONS="" \grep '-head' >/dev/null 2>&1 ; then unicode="${unicode}" fi [[ ${unicode_prefix_flag:-0} -gt 0 ]] && unicode="-${unicode}" fi eval "echo \"$format\"" else while [[ $# -gt 0 ]] ; do token="$1" ; shift case "$token" in s|system) echo "system" ;; esac done fi exit 0 1.15.7. bundle #!/usr/bin/env bash function bundle_not_found() { printf "%b" "$(tput setaf 1)ERROR: Gem bundler is not installed, run \`gem install bundler\` first.$(tput sgr0)\n" exit 127 } # in rvm warn about missing gem if [[ -n "${GEM_HOME:-}" ]] then bundle_not_found else current_bundle="$(dirname $(which $0))" export PATH PATH=":${PATH}:" PATH="${PATH//:${current_bundle}:/:}" PATH="${PATH#:}" PATH="${PATH%:}" if [[ -n "${current_bundle}" ]] && builtin command -v bundle >/dev/null 2>&1 then builtin command bundle "$@" else bundle_not_found fi fi 1.15.8. rake #!/usr/bin/env bash function rake_not_found() { printf "%b" "$(tput setaf 1)ERROR: Gem rake is not installed, run \`gem install rake\` first.$(tput sgr0)\n" exit 127 } # in rvm warn about missing gem if [[ -n "${GEM_HOME:-}" ]] then rake_not_found else current_rake="$(dirname $(which $0))" export PATH PATH=":${PATH}:" PATH="${PATH//:${current_rake}:/:}" PATH="${PATH#:}" PATH="${PATH%:}" if [[ -n "${current_rake}" ]] && builtin command -v rake >/dev/null 2>&1 then builtin command rake "$@" else rake_not_found fi fi 1.15.9. rvm-auto-ruby #!/usr/bin/env bash export HOME="${HOME%%+(\/)}" # Remove trailing slashes if they exist on HOME if (( ${rvm_ignore_rvmrc:=0} == 0 )) then for rvmrc in /etc/rvmrc "$HOME/.rvmrc" do if [[ -f "$rvmrc" ]] then if GREP_OPTIONS="" \grep '^\s*rvm .*$' "$rvmrc" >/dev/null 2>&1 then printf "%b" "\nError: $rvmrc is for rvm settings only.\nrvm CLI may NOT be called from within $rvmrc. \nSkipping the loading of $rvmrc" return 1 else source "$rvmrc" fi fi done fi export rvm_path if [[ -z "${rvm_path:-}" ]] then if (( UID == 0 )) && [[ -d "/usr/local/rvm" ]] then rvm_path="/usr/local/rvm" elif [[ -d "${HOME}/.rvm" ]] then rvm_path="${HOME}/.rvm" elif [[ -d "/usr/local/rvm" ]] then rvm_path="/usr/local/rvm" else echo "Can't find rvm install!" 1>&2 ; exit 1 fi fi true ${rvm_scripts_path:="$rvm_path/scripts"} true ${rvm_environments_path:="$rvm_path/environments"} if [[ -n "$rvm_path" && -s "$rvm_scripts_path/rvm" ]]; then source "$rvm_scripts_path/rvm" > /dev/null 2>&1 elif [[ -s "$HOME/.rvm/scripts/rvm" ]]; then source "$HOME/.rvm/scripts/rvm" > /dev/null 2>&1 elif [[ -s "/usr/local/rvm/scripts/rvm" ]]; then source "/usr/local/rvm/scripts/rvm" > /dev/null 2>&1 else echo "Unable to detect rvm, please manually set the rvm_path env variable." >&2 exit 1 fi [[ -s "$rvm_environments_path/default" ]] && source "$rvm_environments_path/default" rvm_promptless=1 rvm rvmrc load > /dev/null 2>&1 exec ruby "$@" 1.15.10. rvm-installer #!/usr/bin/env bash # echo "65536 * 3 + 256 * 2 + 25" | bc if [[ -n "${BASH_VERSION:-}" ]] && (( 65536 * ${BASH_VERSINFO[0]} + 256 * ${BASH_VERSINFO[1]} + ${BASH_VERSINFO[2]} < 197145 )) then echo "BASH 3.2.25 required (you have $BASH_VERSION)" exit 1 fi shopt -s extglob PS4="+ \${BASH_SOURCE##\${rvm_path:-}} : \${FUNCNAME[0]:+\${FUNCNAME[0]}()} export PS4 set -o errtrace set -o errexit log() { printf "%b\n" "$*" ; return $? ; \${LINENO} > " } fail() { log "\nERROR: $*\n" ; exit 1 ; } if [[ -z "${rvm_tar_command:-}" ]] && builtin command -v gtar >/dev/null then rvm_tar_command=gtar else rvm_tar_command=tar fi if [[ ! " ${rvm_tar_options:-} " =~ " --no-same-owner " ]] && \ $rvm_tar_command --help | GREP_OPTIONS="" \grep -- --no-same-owner >/dev/null then rvm_tar_options="${rvm_tar_options:-} --no-same-owner" rvm_tar_options="${rvm_tar_options## }" fi usage() { printf "%b" " Usage rvm-installer [options] [action] Options [[--]version] <latest|latest-x|latest-x.y|x.y.z> - Install RVM version [--]branch <name> - Install RVM head, from named branch --trace - used to debug the installer script Actions master - Install RVM master branch from wayneeseguin rvm repo (Default). stable - Install RVM stable branch from wayneeseguin rvm repo. help - Display CLI help (this output) Branches: branch branch branch branch <branch> /<branch> <repo>/ <repo>/<branch> Defaults: branch: master repo: wayneeseguin " } #Searches for highest available version for the given pattern # fetch_version 1.10. -> 1.10.3 # fetch_version 1. -> 1.11.0 # fetch_version "" -> 2.0.1 fetch_version() { curl -s https://api.github.com/repos/wayneeseguin/rvm/tags | sed -n '/"name": / {s/^.*".*": "\(.*\)".*$/\1/; p;}' | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n | GREP_OPTIONS="" \grep "^${1:-}" | tail -n 1 } install_release() { typeset _version _version=$1 log "Downloading RVM version ${_version}" get_and_unpack \ https://github.com/wayneeseguin/rvm/tarball/${_version} \ rvm-${_version}.tar.gz \ wayneeseguin-rvm} install_head() { typeset _repo _branch case "$1" in (/*) _repo=wayneeseguin _branch=${1#/} ;; (*/) _repo=${1%/} _branch=master ;; (*/*) _repo=${1%/*} _branch=${1#*/} ;; (*) _repo=wayneeseguin _branch=$1 ;; esac log "Downloading RVM from ${_repo} branch ${_branch}" get_and_unpack \ https://github.com/${_repo}/rvm/tarball/${_branch} \ ${_repo}-rvm-${_branch}.tgz \ ${_repo}-rvm} get_and_unpack() { typeset _url _file _patern _url=$1 _file=$2 _patern=$3 if curl -L ${_url} -o ${rvm_archives_path}/${_file} then true else typeset ret=$? case $ret in (60) log " Could not download '${_url}'. Make sure your certificates are up to date as described above. To continue in insecure mode run 'echo insecure >> ~/.curlrc'. " return 60 ;; (*) log " Could not download '${_url}'. curl returned status '$ret'. " return 1 ;; esac fi [[ -d "${rvm_src_path}/rvm" ]] || \mkdir -p "${rvm_src_path}/rvm" if ! builtin cd "${rvm_src_path}/rvm" then log "Could not change directory '${rvm_src_path}/rvm'." return 2 fi rm -rf ${rvm_src_path}/rvm/* if ! $rvm_tar_command xzf ${rvm_archives_path}/${_file} ${rvm_tar_options:-} then log "Could not extract RVM sources." return 3 fi if ! mv ${_patern}*/* . then log "Could not move RVM sources path." return 4 fi rm -rf ${_patern}* } # Tracing, if asked for. if [[ "$*" =~ --trace ]] || (( ${rvm_trace_flag:-0} > 0 )) then set -o xtrace export rvm_trace_flag=1 fi # Variable initialization, remove trailing slashes if they exist on HOME true \ ${rvm_trace_flag:=0} ${rvm_debug_flag:=0} ${rvm_user_install_flag:=0}\ ${rvm_ignore_rvmrc:=0} HOME="${HOME%%+(\/)}" if (( rvm_ignore_rvmrc == 0 )) then for rvmrc in /etc/rvmrc "$HOME/.rvmrc" do if [[ -s "$rvmrc" ]] then if GREP_OPTIONS="" \grep '^\s*rvm .*$' "$rvmrc" >/dev/null 2>&1 then printf "%b" " Error: $rvmrc is for rvm settings only. rvm CLI may NOT be called from within $rvmrc. Skipping the loading of $rvmrc " return 1 else source "$rvmrc" fi fi done fi if [[ -z "${rvm_path:-}" ]] then if (( UID == 0 )) then rvm_path="/usr/local/rvm" else rvm_path="${HOME}/.rvm" fi fi export HOME rvm_path install_rubies=() install_gems=() # Parse CLI arguments. while (( $# > 0 )) do token="$1" shift case "$token" in --trace) set -o xtrace export rvm_trace_flag=1 ;; --path) if [[ -n "${1:-}" ]] then rvm_path="$1" shift else fail "--path must be followed by a path." fi ;; --branch|branch) # Install RVM from a given branch if [[ -n "${1:-}" ]] then version="head" branch="$1" shift else fail "--branch must be followed by a branchname." fi ;; --user-install|--auto) token=${token#--} token=${token//-/_} export "rvm_${token}_flag"=1 printf "%b" "Turning on ${token/_/ } mode.\n" ;; --without-gems=*) export rvm_without_gems="${token#--without-gems=}" printf "%b" "Installing RVM without gems: ${rvm_without_gems}.\n" ;; --version|version) version="$1" shift ;; head) version="head" branch="master" ;; stable|master) version="head" branch="$token" ;; latest|latest-*|+([[:digit:]]).+([[:digit:]]).+([[:digit:]])) version="$token" ;; --ruby) install_rubies+=( ruby ) ;; --ruby=*) token=${token#--ruby=} install_rubies+=( ${token//,/ } ) ;; --rails) install_gems+=( rails ) ;; --gems=*) token=${token#--gems=} install_gems+=( ${token//,/ } ) ;; help|usage) usage exit 0 ;; *) usage exit 1 ;; esac done case "$rvm_path" in *[[:space:]]*) printf "%b" " It looks you are one of the happy *space* users(in home dir name), RVM is not yet fully ready for it, use this trick to fix it: sudo ln -s \"$HOME/.rvm/\" /$USER.rvm echo \"export rvm_path=/$USER.rvm\" >> \"$HOME/.rvmrc\" and start installing again. " exit 2 ;; esac if (( ${#install_gems[@]} > 0 && ${#install_rubies[@]} == 0 )) then install_rubies=( ruby ) fi if (( ${#install_rubies[@]} > 0 )) then echo "Please read and follow further instructions." echo "Press ENTER to continue." builtin read -n 1 -s -r anykey fi true "${version:=head}" if [[ "$rvm_path" != /* ]] then fail "The rvm install path must be fully qualified. Tried $rvm_path" fi rvm_src_path="$rvm_path/src" rvm_archives_path="$rvm_path/archives" rvm_releases_url="https://rvm.io/releases" for dir in "$rvm_src_path" "$rvm_archives_path" do if [[ ! -d "$dir" ]] then mkdir -p "$dir" fi done # Perform the actual installation, first we obtain the source using whichever # means was specified, if any. Defaults to head. case "${version}" in (head) echo "${branch}" > "$rvm_path/RELEASE" install_head ${branch:-master} || exit $? ;; (latest) echo "${version}" > "$rvm_path/RELEASE" install_release $(fetch_version "") || exit $? ;; (latest-*) echo "${version}" > "$rvm_path/RELEASE" install_release $(fetch_version "${version#latest-}") || exit $? ;; (+([[:digit:]]).+([[:digit:]]).+([[:digit:]])) # x.y.z echo "version" > "$rvm_path/RELEASE" install_release ${version} || exit $? ;; (*) fail "Something went wrong, unrecognized version '$version'" ;; esac # required flag - path to install flags=( --path "$rvm_path" ) if (( rvm_trace_flag == 1 )) then flags+=("--trace") fi if (( rvm_debug_flag == 1 )) then flags+=("--debug") fi if (( rvm_auto_flag == 1 )) then flags+=("--auto") fi if [[ -n "${rvm_without_gems:-}" ]] then flags+=("--without-gems=${rvm_without_gems}") fi chmod +x ./scripts/install ./scripts/install "${flags[@]}" ( source ${rvm_scripts_path:-${rvm_path}/scripts}/rvm source ${rvm_scripts_path:-${rvm_path}/scripts}/version __rvm_version if (( ${#install_rubies[@]} > 0 )) then { echo "Ruby (and needed base gems) for your selection will be installed shortly." echo "Before it happens, please read and execute the instructions below." echo "Please use a separate terminal to execute any additional commands." echo "Press 'q' to continue." } | less fi for _ruby in ${install_rubies[@]} do command rvm install ${_ruby} -j 2 done for _ruby in ${install_rubies[@]} do # set the first one as default, skip rest rvm alias create default ${_ruby} break done for _gem in ${install_gems[@]} do rvm all do gem install ${_gem} done if (( ${#install_rubies[@]} > 0 )) then printf "%b" " * To start using RVM you need to run \`source $rvm_path/scripts/rvm\` in all your open shell windows, in rare cases you need to reopen all shell windows. " fi if [[ "${install_gems[*]}" =~ "rails" ]] then printf "%b" " * To start using rails you need to run \`rails new <project_dir>\`. " fi ) 1.16. docs 1.16.1. vm_setup.md Setting up a VM -----------------------The only real requirement to allow testing of RVM on a VM is that the VM be reachable by ssh. If you choose to run your VMs on [VirtualBox] and take care with a few snapshots then you can use some extra rake commands that expedite testing. Specifically you can reset+start and stop the VMs using: rake vbox:start rake vbox:stop As an example, build a [Ubuntu] VM on [VirtualBox] using the following: - name: ubuntu Linux/Ubuntu 512 MB memory 8 GB dynamically resizing drive Add the iso to the cd/dvd device under Settings > Storage. Now start the server and install ubuntu (use default settings unless specified): - user/password: vboxtest - select 'OpenSSH server' in packages to install When the server has rebooted install iso, take a snapshot convenience. Port forwarding and have that be received by and is ready at the login screen, remove the and setup port forwarding. The snapshot is for allows you to ssh to yourself on one port (2220) the VM on another port (22). (Devices > CD/DVD Devices > Remove disk from virtual drive) VBoxManage snapshot ubuntu take RAW VBoxManage controlvm ubuntu poweroff # wait to fully power off VBoxManage modifyvm ubuntu --natpf1 'ubuntu-ssh,tcp,,2220,,22' VBoxManage -q snapshot ubuntu restore RAW VBoxManage startvm ubuntu Transfer your ssh key to the vm. Help to generate ssh keys can be found on [GitHub](http://help.github.com/key-setup-redirect): scp -P 2220 -o UserKnownHostsFile=/dev/null ~/.ssh/id_rsa.pub vboxtest@localhost:id_rsa.pub Setup SSH for your user: vm: vm: vm: vm: mkdir .ssh mv id_rsa.pub .ssh/authorized_keys chmod 0700 .ssh chmod 0600 .ssh/authorized_keys Remove the login banner (cleans up test output) and exit. vm: sudo rm /etc/motd vm: exit Now take some standard snapshots. By taking them at the login screen you can reset to a running VM, which avoids startup overhead. VBoxManage snapshot ubuntu take BASE VBoxManage snapshot ubuntu take CURRENT VBoxManage controlvm ubuntu poweroff To cleanup the port forwarding (run later, if ever): VBoxManage modifyvm ubuntu --natpf1 delete 'ubuntu-ssh' Now add configs for this VM to config/ssh: Host ubuntu HostName localhost Port 2220 User vboxtest Note that the Host, Port, and User should match up to the values you used during the VM setup. To add additional VMs, for instance to test on different operating systems, choose another name/port and repeat. [VirtualBox]: http://www.virtualbox.org/ [Ubuntu]: http://www.ubuntu.com/ 1.16.2. vm_tests.md VM Tests ============================================================================= RVM lives in the shell and so is tested in a shell. To make things easier, RVM has the ability to test on one or more virtual machines. The setup only requires that VMs be reachable by ssh, however you get a few helper tasks if you run your VMs using [VirtualBox]. See below for an overview of the VM test architecture. Running Locally -----------------------To run locally (generally not recommended due to possible side effects): ./vboxtest/test_suite.sh Or, equivalently: rake vbox:local_test To add another test suite, make a script in the test directory that ends with `_test.sh` and ensure it is executable. Then follow this pattern: #!/bin/sh ######################################################################## TEST_CASE=$(basename "$0") ######################################################################## . ${0%/$TEST_CASE}/../test_helper.sh test_echo_echos_a_string_to_stdout () { # The assert_equal method will check that the echo command exits # with status 0, and that the stdout is 'hello world'. # # There are similar assertions to just check the exit status # or just check stdout. assert_equal 0 "$( echo 'hello world' )" $LINENO <<stdout hello world stdout # Write as many assertions as you please in a given method. } run_test_case "$0" You can write as many test methods as you like... just follow the same conventions as in Test::Unit (ie start the method with `test_`). See the tests for more examples. Running on VMs -----------------------First set up some virtual machines by following the instructions in doc/vm_setup. Now to run the tests: # starts each of the VMs rake vbox:start # copies the test scripts to each vm and runs the test suite on each rake vbox:remote_test # stops each of the VMs rake vbox:stop Or you can run the whole shebang with: rake vbox:test If you aren't running your VMs on VirtualBox and as set up in the docs, then the start/stop commands won't work. can use the `vbox:remote_test` task, you just need to manage your VMs manually. Overview of VM Test Architecture ============================================================================== For those interested in the details... The basic plan is to copy scripts to a VM and then execute one of them to run the test suite. The vboxtest.sh script does just that - it makes a directory on each VM, copies scripts to it, then remotely executes the test runner, all via ssh. As it does so, output is sent back to your terminal. The trick is to use ssh with a config file. The config file allows you to specify the options used by ssh in one place and access them by host name. That way you can provide a simple list of hosts to vboxtest.sh rather than a varied and complex set of connection information. As a convenience the You still `vbox:remote_test` task runs vboxtest.sh with all hosts in config/ssh. The beauty of this setup is that it can go anywhere ssh can go to... at the level of vboxtest.sh, it's pure ssh... and it can do so with a standard ssh config file. VirtualBox -----------------------You don't have to use VirtualBox, but if you do then you can work a few more tricks. Specifically you can name your VirtualBox VMs the same as each host. So make a VirtualBox VM named 'ubuntu' and add a host named 'ubuntu', a VM named 'debian' and a host named 'debian'. Then you setup port forwarding so that you can ssh to localhost:2220 and that goes to ubuntu:22 and localhost:2221 to debian:22. If you've been consistent about your setup you can reuse a lot of the ssh options giving you a tidy, scalable config file like this: Host ubuntu Port 2220 Host debian Port 2221 # Defaults used by all hosts Host * HostName localhost User vboxtest Since your VirtualBox VMs are named the same as the hosts, you can pull them out and have rake start/stop the VMs for you using the VBoxManage command (which comes with VirtualBox). The SSH Config File -----------------------A couple ssh options can be used to expedite testing: # loosen up the ssh checks so you just go without being 100% secure # (good for a test environment) UserKnownHostsFile /dev/null StrictHostKeyChecking no IdentitiesOnly yes # setup a master socket so that the full ssh exchange doesn't have # to happen every time you connect (which is 3 times per-host). ControlMaster auto ControlPath /tmp/socket-%r@%h:%p The master socket drastically reduces overhead. Note that the master socket is cleaned up automatically when the VM is shut down. [VirtualBox]: http://www.virtualbox.org/ 1.16.3. rebuild.sh #!/usr/bin/env bash # # Generating rvm self documents # # uncomment for debugging #set -x # checking system requirements [[ `which asciidoc 2> /dev/null` ]] || (echo "'asciidoc' is not installed on your system, exiting..."; exit 1) [[ `which docbook2man 2> /dev/null` ]] || (echo "'docbook2x' is not installed on your system, exiting..."; exit 1) DIRNAME=$(dirname $0) rvm_base_dir=$(cd $DIRNAME/../; pwd) rvm_docs_src_dir=${rvm_base_dir}/docs rvm_tmp_dir=${rvm_base_dir}/tmp rvm_docs_target_man_dir=${rvm_base_dir}/man \mkdir -p ${rvm_tmp_dir} \mkdir -p ${rvm_docs_target_man_dir} echo "Starting doc generation run through." # processing manpages find ${rvm_docs_src_dir} -type f -name *.txt | while read rvm_manpage_file; do # # # # # # trying to detect manpage name automatically (just for fun, I don't think, that rvm will ever have more than one manpage :) The name of the generated manpage is initially specified within the source file in asciidoc format, so we'll do some simple parsing We assume, that it will be specified at one of the 3 (three) first lines of the source file. # it should be something like 'RVM(1)' rvm_manpage_name_full="$(head -n 3 < "$rvm_manpage_file" | \grep -o '^[^(]*[(][^)]*[)]$')" if [[ -z "${rvm_manpage_name_full}" ]]; then echo "Unable to detect manpage name, stopping build process..." 1>&2 exit 1 fi # we need smth like 'rvm.1' rvm_manpage_name="$(echo "$rvm_manpage_name_full" | sed "s|(|.|;s|)||" | tr '[[:upper:]]' '[[:lower:]]')" # we need '1' rvm_manpage_name_part=$(echo "$rvm_manpage_name" | cut -d '.' -f 2) # So, the manpage directory will be the following: rvm_manpage_dir="$rvm_docs_target_man_dir/man$rvm_manpage_name_part" mkdir -p "$rvm_manpage_dir" echo "Generating manpage format from source file for $rvm_manpage_name" a2x -d manpage -f manpage -D "$rvm_manpage_dir" "$rvm_manpage_file" > /dev/null 2>&1 if [[ "$?" -gt 0 ]]; then echo "Unable to generate manpage for $rvm_manpage_name_full" else \rm -f "$( echo "$rvm_manpage_file" | sed 's/.txt$/.xml/')" # compression is optional, but gzip check added for neatness if command -v gzip >/dev/null 2>&1; then echo "gzip compressing the manpage" gzip < "$rvm_manpage_dir/$rvm_manpage_name" > "$rvm_manpage_dir/$rvm_manpage_name.gz" fi fi done # vim: ft=sh 1.16.4. rvm.txt RVM(1) ====== NAME ---rvm - The Ruby Version Manager SYNOPSIS -------*rvm* ['FLAGS'] ['OPTIONS'] 'ACTION' ['IMPLEMENTATION'[,'IMPLEMENTATION'[,'...']] DESCRIPTION ----------RVM is a command line tool which allows us to easily install, manage and work with multiple ruby environments from interpreters to sets of gems. FLAGS ----*--head*:: with update, updates rvm to git head version. *--rubygems*:: with update, updates rubygems for selected ruby *--default*:: with ruby select, sets a default ruby for new shells. *--debug*:: Toggle debug mode on for very verbose output. *--trace*:: Toggle trace mode on to see EVERYTHING rvm is doing. *--force*:: Force install, removes old install & source before install. *--summary*:: Used with rubydo to print out a summary of the commands run. *--latest*:: with gemset --dump skips version strings for latest gem. *--gems*:: with uninstall/remove removes gems with the interpreter. *--docs*:: with install, attempt to generate ri after installation. *--reconfigure*:: Force ./configure on install even if Makefile already exists. OPTIONS ------*-v, --version*:: Emit rvm version loaded for current shell. *-l, --level*:: patch level to use with rvm use / install *--bin*:: path for binaries to be placed ('~/.rvm/bin/') *--source*:: src directory to use ('~/.rvm/src/') *--archives*:: directory for downladed files ('~/.rvm/archives/') *-S*:: Specify a script file to attempt to load and run (rubydo). *-e*:: Execute code from the command line. *-G*:: root gem path to use *--gems*:: Used to set the 'gems_flag', use with 'remove' to remove gems. *--archive*:: Used to set the 'archive_flag', use with 'remove' to remove archive. *--patch*, *--patches*:: With any ruby build from source, allows you to specify patch paths and patch names to be applied prior to building. Values should be a relative / absolute path to a patch or the name of known patch / patchset. Optionally, paths or names may be followed by '%someinteger' - e.g. '--patches mypatch%2' - where the number following the % specifies the value of the -p argument to patch, defaulting to two. *-C, --configure*:: custom configure options. If you need to pass several configure options then append them comma separated: '-C --...,--...,--...'. *--nice*:: process niceness (for slow computers, default 0) *--ree-options*:: Options passed directly to ree's './installer' on the command line. ACTIONS ------*usage*:: Show this usage information. *version*:: Show the rvm version installed in rvm_path. *use*:: Setup current shell to use a specific ruby version. *reload*:: Reload rvm source itself (useful after changing rvm source). *env*:: Displays information about an environment specified but the given ruby string. Useful for getting a sourceable path or an evaluatable set of shell variable declarations. *implode*:: (seppuku) removes the rvm installation completely. This means everything in $rvm_path ('~/.rvm'). This does not touch your profiles. However, this means that you must manually clean up your profiles and remove the lines which source RVM. *update*:: Upgrades rvm to the latest version. (If you experience bugs try this first with --head). *reset*:: Remove current and stored default & system settings. (If you experience odd behavior try this second). *info*:: Show the *current* environment information for current ruby. *debug*:: Show info plus additional information for common issues. *install*:: Install one or many ruby versions. https://rvm.io/rubies/installing/ *uninstall*:: Uninstall one or many ruby versions, leaves their sources. *remove*:: Uninstall one or many ruby versions and remove their sources. *wrapper*:: Generates a set of wrapper executables for a given ruby with the specified ruby and gemset combination. Used under the hood for passenger support and the like. *do \**:: Runs the specified command against specified and/or all rubies. *tests*:: Runs 'rake test' across selected ruby versions. *specs*:: Runs 'rake spec' across selected ruby versions. *monitor*:: Monitor cwd for testing, run 'rake {spec,test}' on changes. *gemset*:: gemsets: https://rvm.io/gemsets/ *gemdir*:: Display the path to the current gem directory ('$GEM_HOME'). *srcdir*:: Display the path to rvm source directory (may be yanked). *fetch*:: Performs an archive / src fetch only of the selected ruby. *list*:: Show currently installed rubies, interactive output. https://rvm.io/rubies/list/ *pkg*:: Install a dependency package {readline,iconv,zlib,openssl}. https://rvm.io/packages/ *notes*:: Display notes, with operating system specifics. *export*:: Temporarily set an environment variable in the current shell. *unexport*:: Undo changes made to the environment by 'rvm export'. *requirements*:: Show additional OS specific dependencies/requirements for building various rubies. IMPLEMENTATION -------------*ruby*:: MRI/YARV Ruby (The Gold Standard) {1.8.6,1.8.7,1.9.1,1.9.2...} *jruby*:: JRuby, Ruby interpreter on the Java Virtual Machine. *rbx*:: Rubinius *ree*:: Ruby Enterprise Edition, MRI Ruby with several custom patches for performance, stability, and memory. *macruby*:: MacRuby, insanely fast, can make real apps (Mac OS X Only). *maglev*:: GemStone Ruby, awesome persistent ruby object store. *ironruby*:: IronRuby, NOT supported yet. Looking for volunteers to help. *system*:: Use the system ruby (eg. pre-rvm state). *default*:: Use rvm set default ruby and system if it hasn't been set. https://rvm.io/rubies/default/ RESOURCES --------https://rvm.io/[Main web site] https://www.pivotaltracker.com/projects/26822[Online issue-tracker] COPYING ------Copyright (c) 2009 Wayne E. Seguin See LICENCE file for details. //// # vim:ft=asciidoc //// 1.17. lib 1.17.1. rvm.rb # == Ruby Version Manager - Ruby API raise "RVM - Ruby integration was extracted to a separate gem, \ it should be installed by default with RVM, \ remove the `$LOAD_PATH.unshift` line and all should be fine again." 1.17.2. rvm 1.17.2.1. capistrano.rb # Recipes for using RVM on a server with capistrano. raise "RVM - Capistrano integration was extracted to a separate gem, \ install: `gem install rvm-capistrano` and remove the `$LOAD_PATH.unshift` line, \ note also the 'set :rvm_type, :user' is now the default (instead of :system)." 1.18. scripts 1.18.1. color #!/usr/bin/env bash # # # # # # set colors, separate multiple selections with coma, order is not important using bold in one definition requires resetting it in others with offbold using background in one color requires resetting it in others with bdefault example: rvm_error_color=bold,red rvm_notify_color=offbold,green case "${TERM:-dumb}" in (dumb|unknown) exit 0 ;; esac builtin command -v tput >/dev/null && tput sgr0 >/dev/null || exit 0 for color in ${1//,/ } do case "${color:-}" in # regular colors black) tput setaf ;; red) tput setaf ;; green) tput setaf ;; yellow) tput setaf ;; blue) tput setaf ;; magenta) tput setaf ;; cyan) tput setaf ;; white) tput setaf ;; 0 1 2 3 4 5 6 7 # emphasized (bolded) colors bold) tput smso ;; offbold) tput rmso ;; # background colors bblack) tput setab ;; bred) tput setab ;; bgreen) tput setab ;; byellow) tput setab ;; bblue) tput setab ;; bmagenta) tput setab ;; bcyan) tput setab ;; bwhite) tput setab ;; 0 1 2 3 4 5 6 7 # Defaults default) tput setaf 9 ;; bdefault) tput setab 9 ;; # Reset *) tput sgr0 ;; esac done 1.18.2. package #/usr/bin/env bash 1.18.3. hook #!/usr/bin/env bash # silence ZSH redefinitions typeset rvm_verbose_flag rvm_debug_flag hooks >/dev/null 2>/dev/null true ${rvm_verbose_flag:=0} ${rvm_debug_flag:=0} "${rvm_hook:=}" if [[ -n "$rvm_hook" ]] then if [[ "$PWD/.rvm/hooks/$rvm_hook" == "$rvm_hooks_path/$rvm_hook" ]] then hooks=( "$rvm_hooks_path/$rvm_hook") else hooks=("$PWD/.rvm/hooks/$rvm_hook" "$rvm_hooks_path/$rvm_hook") fi for hook in "${hooks[@]}" do if [[ -s "$hook" ]] then if (( rvm_verbose_flag > 0 )) || (( rvm_debug_flag > 0 )) then rvm_log "Running $hook" fi source "$hook" else continue fi done fi unset rvm_hook hooks 1.18.4. extract #/usr/bin/env bash 1.18.5. monitor #!/usr/bin/env bash original_ruby_strings=$rvm_ruby_strings original_ruby_string=$rvm_ruby_string source "$rvm_scripts_path/base" rvm_monitor_sleep="${rvm_monitor_sleep:-2}" timestamp() { if [[ "Darwin" == "$(uname)" ]] ; then echo $(stat -f "%m" $1) else echo $(stat -c "%Y" $1) fi } push_if_timestamp_changed() { typeset file file_timestamp time file=$1 file_timestamp=$(timestamp "$file") eval "time=\$${framework}_timestamp" if [[ "$file_timestamp" -gt $time ]] then array_push "changed_${framework}_files" $file fi } update_timestamp() { if [[ -d "${1}/" ]] then \touch "$rvm_path/${$}_${1}_timestamp" eval "${1}_timestamp=\$(timestamp \"$rvm_path/${$}_${1}_timestamp\")" fi } rvm_warn "rvm monitor is deprecated, take a look on autotest, guard, watchr or ruby-inotify" update_timestamp "test" update_timestamp "spec" while : ; do changed_test_files=() ; changed_spec_files=() ; changed_code_files=() for file in lib/**/*.rb lib/*.rb app/**/*.rb app/*.rb ; do if [[ -f "$file" ]] ; then push_if_timestamp_changed $file "code" ; fi done for framework in test spec ; do if [[ -d "$framework/" ]] ; then for file in ${framework}/**/*_${framework}.rb ${framework}/*_${framework}.rb ; do if [[ -f "$file" ]] ; then push_if_timestamp_changed $file $framework fi done if [[ "$(array_length "changed_${framework}_files")" -gt 0 ]] ; then rvm_ruby_strings=$original_ruby_strings rvm_ruby_string=$original_ruby_string if [[ "spec" == "$framework" ]] ; then rvm_action="spec" rvm_ruby_args="spec/spec_helper.rb ${changed_spec_files[*]}" "$rvm_scripts_path/set" $rvm_action $rvm_ruby_args elif [[ "test" == "$framework" ]] ; then rvm_action="ruby" rvm_ruby_args=" -r$(echo "${changed_test_files[*]}" | sed 's/ / -r/g') test/test_helper.rb" "$rvm_scripts_path/set" $rvm_action $rvm_ruby_args fi update=1 fi if [[ "$(array_length "changed_code_files")" -gt 0 ]] ; then rvm_ruby_strings=$original_ruby_strings rvm_ruby_string=$original_ruby_string if [[ "spec" == "$framework" ]] ; then rvm_action="spec" rvm_ruby_args="spec/" "$rvm_scripts_path/set" $rvm_action $rvm_ruby_args elif [[ "test" == "$framework" ]] ; then rvm_action="rake" rvm_ruby_args="test" "$rvm_scripts_path/set" "$rvm_action" $rvm_ruby_args fi update=1 fi fi if [[ "$update" -eq 1 ]] ; then update_timestamp $framework fi done unset update changed_test_files changed_spec_files sleep $rvm_monitor_sleep done 1.18.6. selector #!/usr/bin/env bash # __rvm_select implementation version patch_level __rvm_select() { true ${rvm_gemset_name:=} typeset _original_env_string _original_env_string=${rvm_env_string} # Set Variable Defaults export GEM_HOME GEM_PATH MY_RUBY_HOME RUBY_VERSION IRBRC export rvm_env_string rvm_action rvm_alias_expanded rvm_archive_extension rvm_bin_flag rvm_bin_path rvm_configure_flags rvm_debug_flag rvm_default_flag rvm_delete_flag rvm_docs_type rvm_dump_environment_flag rvm_error_message rvm_expanding_aliases rvm_file_name rvm_gemdir_flag rvm_gemset_name rvm_gemstone_package_file rvm_gemstone_url rvm_head_flag rvm_hook rvm_install_args rvm_install_on_use_flag rvm_llvm_flag rvm_loaded_flag rvm_make_flags rvm_niceness rvm_nightly_flag rvm_only_path_flag rvm_parse_break rvm_patch_names rvm_patch_original_pwd rvm_pretty_print_flag rvm_proxy rvm_quiet_flag rvm_ree_options rvm_reload_flag rvm_remove_flag rvm_ruby_alias rvm_ruby_aliases rvm_ruby_args rvm_ruby_binary rvm_ruby_bits rvm_ruby_configure rvm_ruby_file rvm_ruby_gem_home rvm_ruby_gem_path rvm_ruby_global_gems_path rvm_ruby_home rvm_ruby_interpreter rvm_ruby_irbrc rvm_ruby_load_path rvm_ruby_major_version rvm_ruby_make rvm_ruby_make_install rvm_ruby_minor_version rvm_ruby_mode rvm_ruby_name rvm_ruby_package_file rvm_ruby_package_name rvm_ruby_patch rvm_ruby_patch_level rvm_ruby_release_version rvm_ruby_repo_url rvm_ruby_require rvm_ruby_revision rvm_ruby_selected_flag rvm_ruby_sha rvm_ruby_string rvm_ruby_strings rvm_ruby_tag rvm_ruby_url rvm_ruby_user_tag rvm_ruby_version rvm_script_name rvm_sdk rvm_silent_flag rvm_sticky_flag rvm_system_flag rvm_token rvm_trace_flag rvm_use_flag rvm_user_flag rvm_verbose_flag rvm_wrapper_name rvm_architectures if [[ -z "${rvm_ruby_string:-}" ]] then # First we build rvm_ruby_string from components if it is empty. if [[ -n "${rvm_ruby_interpreter:-}" ]] then rvm_ruby_string="$rvm_ruby_interpreter" fi if [[ -n "${rvm_ruby_version:-}" ]] then rvm_ruby_string="$rvm_ruby_string-$rvm_ruby_version" fi if [[ -n "${rvm_ruby_patch_level:-}" ]] then rvm_ruby_string="$rvm_ruby_string-$rvm_ruby_patch_level" fi if [[ -n "${rvm_ruby_revision:-}" ]] then rvm_ruby_string="$rvm_ruby_string-$rvm_ruby_revision" fi if [[ -n "${rvm_ruby_name:-}" ]] then rvm_ruby_name="$rvm_ruby_string-$rvm_ruby_name" fi fi __rvm_ruby_string || return $? rvm_archive_extension="tar.gz" if [[ -z "${rvm_ruby_interpreter:-}" ]] then rvm_ruby_interpreter="${rvm_ruby_string//-*/}" fi case "${rvm_ruby_interpreter:-missing}" in missing) return 2 ;; macruby) if [[ "Darwin" == "$(uname)" ]] then rvm_ruby_package_name="${rvm_ruby_interpreter}-${rvm_ruby_version}" if (( ${rvm_head_flag:=0} == 1 )) then rvm_ruby_version="" ; rvm_ruby_tag="" rvm_ruby_revision="head" __rvm_db "macruby_repo_url" "rvm_ruby_repo_url" rvm_ruby_url="$rvm_ruby_repo_url" elif [[ "nightly" == "${rvm_ruby_version:-}" ]] then __rvm_db "macruby_nightly_url" "rvm_ruby_url" rvm_ruby_package_name="${rvm_ruby_interpreter}_nightly-${rvm_ruby_version}" rvm_ruby_package_file="$rvm_ruby_package_name" elif [[ -n "${rvm_ruby_version:-}" ]] then __rvm_db "macruby_${rvm_ruby_version}_url" "rvm_ruby_url" [[ -n "${rvm_ruby_url:-}" ]] || __rvm_db "macruby_url" "rvm_ruby_url" rvm_ruby_package_name="MacRuby%20${rvm_ruby_version}.zip" rvm_ruby_package_file="$rvm_ruby_package_name" rvm_ruby_url="$rvm_ruby_url/$rvm_ruby_package_name" else __rvm_db "macruby_version" "rvm_ruby_version" __rvm_db "macruby_url" "rvm_ruby_url" rvm_ruby_package_name="MacRuby%20${rvm_ruby_version}.zip" rvm_ruby_package_file="$rvm_ruby_package_name" rvm_ruby_url="$rvm_ruby_url/$rvm_ruby_package_name" fi rvm_ruby_patch_level="" else rvm_error "MacRuby can only be installed on a Darwin OS." fi ;; rbx|rubinius) rvm_archive_extension="tar.gz" rvm_ruby_interpreter="rbx" rvm_ruby_version=${rvm_ruby_version:-$(__rvm_db "rbx_version")} rvm_ruby_repo_url=${rvm_rbx_repo_url:-$(__rvm_db "rubinius_repo_url")} rbx_url=${rbx_url:-$(__rvm_db "rbx_url")} rvm_ruby_patch_level="" case "${rvm_ruby_version}" in (2.0pre) rvm_ruby_repo_branch="master" ;; (2.0.testing) rvm_ruby_repo_branch="${rvm_ruby_version}" ;; esac if (( ${rvm_head_flag:=0} == 0 )) then rvm_ruby_url="${rbx_url}" rvm_ruby_package_file="rubinius-${rvm_ruby_version}.${rvm_archive_extension}" rvm_ruby_url="$rvm_ruby_url/$rvm_ruby_package_file" else rvm_ruby_version="head" fi if [[ -n "${rvm_rbx_opt:-}" ]] then export RBXOPT="${RBXOPT:=${rvm_rbx_opt}}" fi ;; jruby) rvm_ruby_patch_level="" if (( ${rvm_head_flag:=0} == 1 )) then rvm_ruby_version="head" rvm_ruby_repo_url="${rvm_ruby_repo_url:-$(__rvm_db "jruby_repo_url")}" rvm_ruby_url="${rvm_ruby_repo_url:-$(__rvm_db "jruby_repo_url")}" elif [[ ${rvm_18_flag:-0} == 1 || ${rvm_19_flag:-0} == 1 ]] then rvm_ruby_repo_url="${rvm_ruby_repo_url:-$(__rvm_db "jruby_repo_url")}" rvm_ruby_url="${rvm_ruby_repo_url:-$(__rvm_db "jruby_repo_url")}" rvm_ruby_version="${rvm_ruby_version:-"$(__rvm_db "jruby_version")"}" rvm_ruby_tag="${rvm_ruby_tag:-${rvm_ruby_version}}" else rvm_archive_extension="tar.gz" rvm_ruby_version="${rvm_ruby_version:-"$(__rvm_db "jruby_version")"}" jruby_url="$(__rvm_db "jruby_url")" rvm_ruby_package_file="${rvm_ruby_interpreter}-bin-${rvm_ruby_version}" rvm_ruby_package_name="${rvm_ruby_interpreter}-${rvm_ruby_version}" rvm_ruby_url="${jruby_url}/${rvm_ruby_version}/${rvm_ruby_package_file}.tar.gz" jruby_url="" fi alias jruby_ng="jruby --ng" alias jruby_ng_server="jruby --ng-server" ;; maglev) rvm_ruby_patch_level="" maglev_url="$(__rvm_db "maglev_url")" system="$(uname -s)" if [[ "$MACHTYPE" == x86_64-apple-darwin* ]] then arch="i386" # Anyone else hear circus musik? ;) else arch="$(uname -m)" fi if (( ${rvm_head_flag:=0} == 1 )) || [[ "$rvm_ruby_version" == "head" ]] then rvm_head_flag=1 rvm_ruby_version="head" rvm_ruby_repo_url="${rvm_ruby_repo_url:-$(__rvm_db "maglev_repo_url")}" rvm_ruby_url="${rvm_ruby_repo_url:-$(__rvm_db "maglev_repo_url")}" rvm_gemstone_version=$( command curl -s https://raw.github.com/MagLev/maglev/master/version.txt | GREP_OPTIONS="" \grep ^GEMSTONE | cut -f2 -d) rvm_gemstone_package_file="GemStone-${rvm_gemstone_version}.${system}-${arch}" else rvm_ruby_package_file="MagLev-${rvm_ruby_version}" # removed from 1.0: .${system}-${arch} rvm_ruby_version="${rvm_ruby_version:-"$(__rvm_db "maglev_version")"}" rvm_ruby_package_name="${rvm_ruby_interpreter}-${rvm_ruby_version}" rvm_ruby_url="${rvm_ruby_url:-"$maglev_url/${rvm_ruby_package_file}.${rvm_archive_extension}"}" rvm_gemstone_version=$( version_tag_commit=$( command curl -s http://github.com/api/v2/yaml/repos/show/MagLev/maglev/tags | awk '/MagLev-'${rvm_ruby_version}':/ {print $2 }' ) command curl -s https://raw.github.com/MagLev/maglev/$version_tag_commit/version.txt | GREP_OPTIONS="" \grep ^GEMSTONE | cut -f2 -d) rvm_gemstone_package_file="GemStone-${rvm_gemstone_version}.${system}-${arch}" export MAGLEV_HOME="$rvm_rubies_path/$rvm_ruby_string" fi rvm_gemstone_url="$maglev_url/${rvm_gemstone_package_file}.${rvm_archive_extension}" ;; ironruby) rvm_ruby_patch_level="" if (( ${rvm_head_flag:=0} == 1 )) then rvm_ruby_version="head" rvm_ruby_package_name="${rvm_ruby_string}" rvm_ruby_repo_url="${rvm_ruby_repo_url:-$(__rvm_db "ironruby_repo_url")}" rvm_ruby_url="${rvm_ruby_repo_url:-$(__rvm_db "ironruby_repo_url")}" else rvm_archive_extension="zip" rvm_ruby_version=${rvm_ruby_version:-"$(__rvm_db "ironruby_version")"} rvm_ruby_package_name="${rvm_ruby_interpreter}-${rvm_ruby_version}" rvm_ruby_package_file="${rvm_ruby_interpreter}-${rvm_ruby_version}.${rvm_archive_extension}" rvm_ruby_url="$(__rvm_db "ironruby_${rvm_ruby_version}_url")${rvm_ruby_package_file}" fi export rvm_ruby_version rvm_ruby_string rvm_ruby_package_name rvm_ruby_repo_url rvm_ruby_url rvm_archive_extension ;; ree) rvm_ruby_interpreter=ree rvm_ruby_version=${rvm_ruby_version:-"$(__rvm_db "ree_version")"} case "$rvm_ruby_version" in 1.8.*) true ;; # all good! *) rvm_error "Unknown Ruby Enterprise Edition version: $rvm_ruby_version" ;; esac if [[ -n "${rvm_ruby_patch_level:-0}" ]] then rvm_ruby_patch_level="$(echo $rvm_ruby_patch_level | \sed 's#^p##')" fi rvm_ruby_package_file="ruby-enterprise-$rvm_ruby_version-$rvm_ruby_patch_level" rvm_ruby_url="$(__rvm_db "${rvm_ruby_interpreter}_${rvm_ruby_version}_${rvm_ruby_patch_level}_url")" rvm_ruby_url="${rvm_ruby_url:-$(__rvm_db "${rvm_ruby_interpreter}_${rvm_ruby_version}_url")}" rvm_ruby_url="${rvm_ruby_url}/$rvm_ruby_package_file.tar.gz" ;; kiji) rvm_ruby_interpreter="kiji" rvm_ruby_version="head" rvm_head_flag=1 rvm_ruby_string="kiji-head" rvm_ruby_patch_level="" rvm_ruby_repo_url=${rvm_mput_repo_url:-"$(__rvm_db "kiji_repo_url")"} rvm_ruby_url=$rvm_ruby_repo_url rvm_ruby_configure="" ; rvm_ruby_make="" ; rvm_ruby_make_install="" ;; goruby) rvm_ruby_interpreter="goruby" rvm_ruby_version="head" rvm_ruby_string="goruby" rvm_ruby_patch_level="" rvm_ruby_repo_url=${rvm_mput_repo_url:-"$(__rvm_db "goruby_repo_url")"} rvm_ruby_url=$rvm_ruby_repo_url rvm_ruby_configure="" ; rvm_ruby_make="" ; rvm_ruby_make_install="" ;; tcs) rvm_ruby_interpreter="tcs" rvm_ruby_version="head" rvm_ruby_string="tcs" rvm_ruby_patch_level="" rvm_ruby_repo_url=${rvm_tcs_repo_url:-"$(__rvm_db "tcs_repo_url")"} rvm_ruby_url=$rvm_ruby_repo_url rvm_ruby_repo_branch="${rvm_ruby_repo_branch:-"$(__rvm_db "tcs_repo_branch")"}" export rvm_head_flag=1 rvm_ruby_configure="" ; rvm_ruby_make="" ; rvm_ruby_make_install="" ;; ruby) if [[ -n "${rvm_ruby_patch_level}" ]] then rvm_ruby_package_file="${rvm_ruby_interpreter}-${rvm_ruby_version}-${rvm_ruby_patch_level}" rvm_ruby_package_name="${rvm_ruby_interpreter}-${rvm_ruby_version}-${rvm_ruby_patch_level}" else rvm_ruby_package_file="${rvm_ruby_interpreter}-${rvm_ruby_version}" rvm_ruby_package_name="${rvm_ruby_interpreter}-${rvm_ruby_version}" fi if [[ -z "${rvm_ruby_version:-""}" ]] && (( ${rvm_head_flag:=0} == 0 )) then rvm_error "Ruby version was not specified!" else rvm_ruby_repo_url="${rvm_ruby_repo_url:-"$(__rvm_db "ruby_repo_url")"}" if (( ${rvm_head_flag:=0} == 0 )) then case "${rvm_ruby_version}" in (1.8.4) rvm_archive_extension="tar.gz" ;; (*) rvm_archive_extension="tar.bz2" ;; esac fi fi ;; ext) if [[ -z "${rvm_ruby_name:-${detected_rvm_ruby_name:-}}" ]] then rvm_error "External ruby name was not specified!" fi ;; current) ruby_binary="$(builtin command -v ruby)" if (( $? == 0)) && match "$ruby_binary" "*rvm*" then rvm_ruby_string="$(dirname "$ruby_binary" | xargs dirname | xargs basename)" else rvm_ruby_interpreter="system" fi ;; default|system|user) # no-op? ;; *) if [[ -n "${MY_RUBY_HOME:-""}" ]] then rvm_ruby_string=$(basename $MY_RUBY_HOME) __rvm_select else if [[ -z "${rvm_ruby_string:-""}" ]] then rvm_error "Ruby implementation '$rvm_ruby_interpreter' is not known." return 1 fi fi esac if [[ -n "$rvm_ruby_version" ]] then case "$rvm_ruby_version" in (+([[:digit:]]).+([[:digit:]]).+([[:digit:]])) rvm_ruby_release_version="${rvm_ruby_version/.*/}" rvm_ruby_major_version=${rvm_ruby_version%.*} ; rvm_ruby_major_version=${rvm_ruby_major_version#*.} rvm_ruby_minor_version="${rvm_ruby_version//*.}" ;; (+([[:digit:]]).+([[:digit:]])) rvm_ruby_release_version="${rvm_ruby_version/.*/}" rvm_ruby_major_version="${rvm_ruby_version#*.}" rvm_ruby_minor_version="" ;; esac fi if [[ "${rvm_ruby_interpreter}" == ext ]] then rvm_ruby_home="$rvm_externals_path/$rvm_ruby_string" rvm_ruby_irbrc="$rvm_ruby_home/.irbrc" rvm_ruby_binary="$( readlink $rvm_ruby_home/bin/ruby )" else rvm_ruby_package_name="${rvm_ruby_package_name:-${rvm_ruby_string//-n*}}" rvm_ruby_home="$rvm_rubies_path/$rvm_ruby_string" rvm_ruby_irbrc="$rvm_ruby_home/.irbrc" rvm_ruby_binary="$rvm_ruby_home/bin/ruby" fi # TODO is this right place to do this ? if [[ "maglev" == "$rvm_ruby_interpreter" ]] then export MAGLEV_HOME="$rvm_ruby_home" export GEMSTONE_GLOBAL_DIR=$MAGLEV_HOME fi if [[ "system" != "$rvm_ruby_interpreter" ]] then __rvm_gemset_select case $? in 1|3|4) return 1 ;; esac fi rvm_ruby_selected_flag=1 if [[ -d "${rvm_log_path}/$rvm_ruby_string" ]] then \mkdir -p "${rvm_log_path}/$rvm_ruby_string" fi rvm_ruby_interpreter="${rvm_ruby_interpreter:-system}" } __rvm_use_system() { unset GEM_HOME GEM_PATH MY_RUBY_HOME RUBY_VERSION IRBRC new_path="$(__rvm_remove_rvm_from_path ; printf "%b" "$PATH"):${rvm_bin_path}" if [[ -s "$rvm_path/config/system" ]] then if GREP_OPTIONS="" \grep "MY_RUBY_HOME='$rvm_rubies_path" "$rvm_path/config/system" > /dev/null then # 'system' should *not* point to an rvm ruby. if [[ -f "$rvm_path/config/system" ]] then \rm -f "$rvm_path/config/system" fi else source "$rvm_path/config/system" fi fi if (( ${rvm_default_flag:=0} == 1 )) then "$rvm_scripts_path/alias" delete default &> /dev/null \find "${rvm_bin_path}" -maxdepth 0 -name 'default_*' -delete \rm -f "$rvm_path/config/default" \rm -f "$rvm_environments_path/default" __rvm_rm_rf "$rvm_wrappers_path/default" fi # Check binaries, remove under the condition they're symlinks. if (( ${rvm_user_install_flag:=0} == 0 )) then for binary in ruby gem irb ri rdoc rake erb testrb do full_binary_path="${rvm_bin_path}/$binary" if [[ -L "$full_binary_path" ]] then \rm -f "$full_binary_path" fi done fi if (( ${rvm_verbose_flag:=0} == 1 )) then rvm_log "Now using system ruby." fi __rvm_remove_rvm_from_path new_path="$PATH:${rvm_bin_path}" export rvm_ruby_string="system" } __rvm_use() { typeset new_path binary full_binary_path rvm_ruby_gem_home __rvm_select "$@" || return $? if [[ "system" == ${rvm_ruby_interpreter:="system"} ]] then __rvm_use_system else if [[ ! -d "$rvm_ruby_home" ]] then if [[ ${rvm_install_on_use_flag:-0} -eq 1 ]] then rvm_warn "$rvm_ruby_string is not installed." "$rvm_scripts_path/manage" "install" "$rvm_ruby_string" else rvm_error "$rvm_ruby_string is not installed." rvm_log "To install do: 'rvm install $rvm_ruby_string'" return 1 fi fi if [[ ! -d "$rvm_ruby_gem_home" || -n "${rvm_expected_gemset_name}" ]] then if (( ${rvm_gemset_create_on_use_flag:=0} == 1 || ${rvm_create_flag:=0} == 1 )) then rvm_warn "gemset $rvm_gemset_name is not existing, creating." "$rvm_scripts_path/gemsets" create "$rvm_gemset_name" else rvm_error "Gemset '${rvm_expected_gemset_name}' does not exist, 'rvm gemset create ${rvm_expected_gemset_name}' first, or append '--create'." return 2 fi fi export GEM_HOME GEM_PATH MY_RUBY_HOME RUBY_VERSION IRBRC GEM_HOME="$rvm_ruby_gem_home" GEM_PATH="$rvm_ruby_gem_path" MY_RUBY_HOME="$rvm_ruby_home" RUBY_VERSION="$rvm_ruby_string" IRBRC="$rvm_ruby_irbrc" unset BUNDLE_PATH # Ensure that BUNDLE_PATH is not set! # Handle MagLev pre-installed gems if [[ "maglev" == "$rvm_ruby_interpreter" ]] then GEM_PATH="$GEM_PATH:$MAGLEV_HOME/lib/maglev/gems/1.8/" fi [[ -n "${IRBRC:-}" ]] || unset IRBRC # Ensure the environment file for the selected ruby exists. __rvm_ensure_has_environment_files if (( ${rvm_verbose_flag:=0} == 1 )) then rvm_log "Using ${GEM_HOME/${rvm_gemset_separator:-'@'}/ with gemset }" fi if [[ "$GEM_HOME" != "$rvm_ruby_global_gems_path" ]] then new_path="$GEM_HOME/bin:$rvm_ruby_global_gems_path/bin:$MY_RUBY_HOME/bin:${rvm_bin_path}:$(__rvm_remove_rvm_from_path ;printf "%b" "$PATH")" else new_path="$GEM_HOME/bin:$MY_RUBY_HOME/bin:${rvm_bin_path}:$(__rvm_remove_rvm_from_path ;printf "%b" "$PATH")" fi fi [[ -z "${rvm_ruby_string:-}" ]] || export rvm_ruby_string [[ -z "${rvm_gemset_name:-}" ]] || export rvm_gemset_name if [[ -n "$new_path" ]] then export PATH="$new_path" unset new_path builtin hash -r fi if [[ "$rvm_ruby_string" != "system" ]] then case "${rvm_rvmrc_flag:-0}" in (rvmrc|versions_conf|ruby_version) __rvm_set_${rvm_rvmrc_flag} ;; esac typeset environment_id environment_id="$(__rvm_env_string)" if (( ${rvm_default_flag:=0} == 1 )) && [[ "default" != "${rvm_ruby_interpreter:-}" ]] && [[ "system" != "${rvm_ruby_interpreter:-}" ]] then # Switch the default alias to the new environment id "$rvm_scripts_path/alias" delete default &> /dev/null "$rvm_scripts_path/alias" create default "$environment_id" >& /dev/null fi rvm_default_flag=0 if [[ -n "${rvm_wrapper_name:-}" ]] then "$rvm_scripts_path/wrapper" "$environment_id" "$rvm_wrapper_name" > /dev/null 2>&1 rvm_wrapper_name="" fi if [[ -n "${rvm_ruby_alias:-}" ]] then rvm_log "Attempting to alias $environment_id to $rvm_ruby_alias" "$rvm_scripts_path/alias" delete "$rvm_ruby_alias" > /dev/null 2>&1 rvm_alias_expanded=1 "$rvm_scripts_path/alias" create "$rvm_ruby_alias" "$environment_id" > /dev/null 2>&1 ruby_alias="" ; rvm_ruby_alias="" fi if [[ "maglev" == "${rvm_ruby_interpreter:-""}" ]] then export MAGLEV_HOME="$rvm_ruby_home" export GEMSTONE_GLOBAL_DIR=$MAGLEV_HOME if [[ -x "$MAGLEV_HOME/gemstone/bin/gslist" ]] then "$MAGLEV_HOME/gemstone/bin/gslist" -clv > /dev/null 2>&1 ; result=$? if (( result == 1 )) then "$rvm_ruby_home/bin/maglev" start fi fi fi else if (( ${rvm_default_flag:=0} == 1 )) then if ! builtin command -v __rvm_reset >> /dev/null 2>&1 then source "$rvm_scripts_path/functions/reset" __rvm_reset fi fi fi rvm_hook="after_use" source "$rvm_scripts_path/hook" return 0 } __rvm_ruby_string() { # rvm_ruby_string may designate any of the following items: # * rvm_gemset_name # * rvm_ruby_interpreter # * rvm_ruby_version # * rvm_ruby_patch_level # * rvm_ruby_revision # * rvm_ruby_tag typeset ruby_string gemset_name expanded_alias_name repo_url branch_name ruby_name __rvm_default_flags rvm_expanding_aliases= true \ "${rvm_ruby_version:=}" "${rvm_gemset_name:=}" "${rvm_ruby_interpreter:=}"\ "${rvm_ruby_version:=}" "${rvm_ruby_tag:=}" "${rvm_ruby_patch_level:=}"\ "${rvm_ruby_revision:=}" ${rvm_gemset_separator:="@"} "${rvm_ruby_string:=}"\ ${rvm_expanding_aliases:=0} ${rvm_head_flag:=0} if echo "$rvm_ruby_string" | GREP_OPTIONS="" \grep "${rvm_gemset_separator}" >/dev/null 2>&1 then rvm_gemset_name="${rvm_ruby_string/*${rvm_gemset_separator}/}" rvm_ruby_string="${rvm_ruby_string/${rvm_gemset_separator}*/}" fi # Alias'd rubies if (( rvm_expanding_aliases == 0 )) && [[ -n "${rvm_ruby_string}" && "$rvm_ruby_string" != "system" ]] then if expanded_alias_name="$("$rvm_scripts_path/alias" show "$rvm_ruby_string" 2>/dev/null)" \ && [[ -n "$expanded_alias_name" ]] then rvm_ruby_string="$expanded_alias_name" elif [[ "$rvm_ruby_string" == default ]] then # Default is not a known value. Instead, we need to therefore set it to system. rvm_ruby_string="system" fi fi if echo "$rvm_ruby_string" | GREP_OPTIONS="" \grep "${rvm_gemset_separator}" >/dev/null 2>&1 ; then rvm_gemset_name="${rvm_ruby_string/*${rvm_gemset_separator}/}" rvm_ruby_string="${rvm_ruby_string/${rvm_gemset_separator}*/}" fi # Stash the ruby string. ruby_string="${rvm_ruby_string:-}" gemset_name="${rvm_gemset_name:-}" repo_url="${rvm_ruby_repo_url:-}" branch_name="${rvm_ruby_repo_branch:-}" ruby_name="${rvm_ruby_name:-}" __rvm_unset_ruby_variables rvm_ruby_repo_url="${repo_url:-}" rvm_ruby_repo_branch="${branch_name:-}" rvm_ruby_name="$ruby_name" if [[ -n "$gemset_name" ]] then rvm_gemset_name="$gemset_name" rvm_sticky_flag=1 # <- not sold on this. fi strings=($(echo ${ruby_string//-/ })) if (( ${#strings[@]} == 0 )) then if echo "${GEM_HOME:-}" | GREP_OPTIONS="" \grep "${rvm_path}" >/dev/null 2>&1 then # Current Ruby strings="${GEM_HOME##*\/}" strings="${strings/%${rvm_gemset_separator:-"@"}*}" rvm_ruby_string="$strings" strings=( $(echo ${rvm_ruby_string//-/ }) ) else strings=(system) rvm_ruby_string="system" fi fi for string in ${strings[@]} do case "$string" in (head) rvm_ruby_patch_level="" rvm_ruby_revision="" rvm_ruby_tag="" export rvm_head_flag=1 ;; (system) rvm_ruby_interpreter="system" rvm_ruby_patch_level="" rvm_ruby_tag="" rvm_ruby_revision="" rvm_ruby_version="" rvm_gemset_name="" rvm_head_flag=0 return 0 ;; (ext|external) rvm_ruby_interpreter="ext" rvm_ruby_patch_level="" rvm_ruby_tag="" rvm_ruby_revision="" rvm_ruby_version="" rvm_head_flag=0 unset strings[__array_start] strings=( ${strings[@]} ) strings="${strings[*]}" rvm_ruby_name="${strings// /-}" break ;; (nightly) rvm_ruby_version="nightly" rvm_nightly_flag=1 break ;; (preview*) rvm_ruby_patch_level="$string" ;; (rc[[:digit:]]*) rvm_ruby_patch_level="$string" ;; ([[:digit:]].[[:digit:]]*) #TODO: use normal code for rbx! if [[ "${rvm_ruby_interpreter}" == "rbx" ]] then if [[ -z "${rvm_ruby_version}" ]] then rvm_ruby_version="${string}" elif [[ -z "${rvm_ruby_patch_level}" ]] then rvm_ruby_patch_level="${string}" else rvm_error "Unknown ruby interpreter string component: '$string'." return 1 fi else case "$string" in (0.+([[:digit:]])|0.+([[:digit:]]).+([[:digit:]])|1.+([[:digit:]]).+([[:digit:]])|2.+([[:digit:]]).+([[:digit:]])|1.+([[:dig it:]]).+([[:digit:]]).+([[:digit:]])|1.+([[:digit:]])) rvm_ruby_version="$string" rvm_ruby_revision="" rvm_ruby_tag="" ;; (1.+([[:digit:]]).+([[:digit:]]).+([[:alnum:]])) case "${rvm_ruby_interpreter:-""}" in (jruby) rvm_ruby_version="$string" ;; (*) rvm_error "Unknown ruby interpreter version: '$string'." return 1 ;; esac ;; (*) rvm_error "Unknown ruby interpreter version: '$string'." return 1 ;; esac fi ;; (p[[:digit:]]*) rvm_ruby_patch_level="$string" ;; ([[:digit:]][[:digit:]]*) case "${rvm_ruby_interpreter:-""}" in (ree) rvm_ruby_patch_level="$string" rvm_ruby_revision="" ;; (kiji) rvm_ruby_patch_level="$string" rvm_ruby_revision="" ;; (rbx) rvm_ruby_patch_level="$string" ;; (maglev) rvm_ruby_version="$string" rvm_ruby_revision="" rvm_ruby_patch_level="" ;; (*) rvm_ruby_revision="r$string" ;; esac ;; (r[[:digit:]]*) rvm_ruby_patch_level="" rvm_ruby_revision="$string" ;; (s[[:alnum:]]*) rvm_ruby_revision="" rvm_ruby_sha="${string#s}" ;; (tv[[:digit:]]*|t[[:digit:]]*) rvm_ruby_patch_level="" ; rvm_ruby_revision="" rvm_ruby_tag="$string" ;; (m[[:digit:]]*) rvm_ruby_mode="$string" ;; (u[[:alnum:]]*) rvm_ruby_patch_level="" ; rvm_ruby_revision="" ; rvm_ruby_tag="" ; rvm_ruby_patch="" rvm_ruby_user_tag="$string" ;; (a[[:digit:]][[:digit:]]*) rvm_ruby_bits="$string" # Architecture ;; (b[[:digit:]]*) rvm_ruby_repo_branch="${string}" rvm_head_flag=1 ;; (ruby|rbx|jruby|macruby|ree|kiji|rubinius|maglev|ironruby|goruby|tcs) rvm_ruby_interpreter="$string" ;; ([[:alpha:]]*([[:alnum:]]|_)) rvm_ruby_name="$string" ;; (*) rvm_error "Unknown ruby interpreter string component: '$string'." return 1 ;; esac done if [[ -z "${rvm_ruby_interpreter:-""}" ]] then # Detect interpreter based on version. case "$rvm_ruby_version" in (1.[8-9]*) rvm_ruby_interpreter="ruby" ;; (0.[5-6]*) rvm_ruby_interpreter="macruby" ;; (1.[0-4]*) rvm_ruby_interpreter="rbx" ;; (1.[5-7]*) rvm_ruby_interpreter="jruby" ;; (2.*) rvm_error "Version '$rvm_ruby_version' is to confusing to select ruby interpreter." return 2 ;; esac fi # Unspecified version rvm_ruby_version="${rvm_ruby_version:-}" if [[ -z "${rvm_ruby_version:-}" && "${rvm_ruby_interpreter}" != "ext" ]] && (( ${rvm_head_flag:=0} == 0 )) then rvm_ruby_version="${rvm_ruby_version:-"$( __rvm_db "${rvm_ruby_interpreter}_version" )"}" fi if [[ -z "${rvm_ruby_version:-}" ]] then rvm_ruby_string="${rvm_ruby_interpreter}" else rvm_ruby_string="${rvm_ruby_interpreter}-${rvm_ruby_version}" fi if [[ "${rvm_ruby_interpreter}" == "ext" ]] then true # skip checking for external rubies elif (( ${rvm_head_flag:=0} == 1 )) then rvm_ruby_string="${rvm_ruby_string}-head" elif [[ -n "${rvm_ruby_revision:-}" ]] then rvm_ruby_string="${rvm_ruby_string}-${rvm_ruby_revision}" elif [[ -n "${rvm_ruby_sha:-}" ]] then rvm_ruby_string="${rvm_ruby_string}-s${rvm_ruby_sha}" elif [[ -n "${rvm_ruby_tag:-}" ]] then rvm_ruby_string="${rvm_ruby_string}-${rvm_ruby_tag}" elif [[ -n "${rvm_ruby_patch_level:-}" ]] then rvm_ruby_string="${rvm_ruby_string}-${rvm_ruby_patch_level}" elif [[ -n "${rvm_ruby_user_tag:-}" ]] then rvm_ruby_string="${rvm_ruby_string}-${rvm_ruby_user_tag}" else patch_level="$( __rvm_db "${rvm_ruby_interpreter}_${rvm_ruby_version}_patch_level" )" if [[ -n "${patch_level:-""}" ]] then case "$rvm_ruby_interpreter" in ree|kiji|rbx) # REE, Kiji & Rubinius use dates for their patch levels. rvm_ruby_patch_level="${patch_level}" ;; *) # MRI uses -pN+ to specify the patch level. rvm_ruby_patch_level="p${patch_level}" ;; esac fi if [[ -n "${rvm_ruby_patch_level:-""}" ]] then rvm_ruby_patch_level="${rvm_ruby_patch_level/#pp/p}" rvm_ruby_patch_level="${rvm_ruby_patch_level/#prc/rc}" rvm_ruby_string="${rvm_ruby_string}-${rvm_ruby_patch_level}" case "$rvm_ruby_interpreter" in (ree|kiji|rbx) rvm_ruby_string="${rvm_ruby_string//-p*/-}" ;; (*) rvm_ruby_string="${rvm_ruby_string//-pp/-p}" rvm_ruby_string="${rvm_ruby_string//-prc/-rc}" ;; esac fi fi if [[ -n "${rvm_ruby_name:-}" ]] then rvm_ruby_string="${rvm_ruby_string}-${rvm_ruby_name}" # record the name for validation of -n option detected_rvm_ruby_name="${rvm_ruby_name}" # clean the name so it is not added again (rbx -n install problem) rvm_ruby_name="" else # record the no name for validation of -n option detected_rvm_ruby_name="" fi } __rvm_ruby_strings_exist() { for rvm_ruby_string in ${@//,/ } do rvm_verbose_flag=0 __rvm_use "${rvm_ruby_string}" >/dev/null 2>&1 || return $? printf "%b" "${rvm_ruby_string}${rvm_gemset_name:+@}${rvm_gemset_name:-}\n" done unset rvm_ruby_string } 1.18.7. get #!/usr/bin/env bash source "$rvm_scripts_path/base" get_usage() { cat -v "$rvm_help_path/get" } get_via_installer() { curl -L get.rvm.io | bash -s -- $@ || return $? typeset -x rvm_hook rvm_hook="after_update" source "$rvm_scripts_path/hook" return 0 } case "$1" in (stable|master|head|branch|latest|latest-*|[0-9]*.[0-9]*.[0-9]*) get_via_installer $@ ;; (help) get_usage true ;; (*) get_usage ;; esac exit $? 1.18.8. docs #!/usr/bin/env bash rvm_base_except="selector" source "$rvm_scripts_path/base" rvm_docs_ruby_string="$(__rvm_env_string | awk -F"${rvm_gemset_separator:-"@"}" '{print $1}')" if [[ "$rvm_docs_ruby_string" == "system" || -z "$rvm_docs_ruby_string" ]] then rvm_error "Currently 'rvm docs ...' does not work with non-rvm rubies." exit 1 fi if [[ ! -d "${rvm_src_path}/$rvm_docs_ruby_string" ]] then rvm_error "'rvm docs ...' requires ruby sources to be available, run \`rvm reinstall $rvm_docs_ruby_string" exit 2 fi rvm_docs_type="${rvm_docs_type:-rdoc}" # Ensure we have the doc directories. if [[ ! -d "${rvm_docs_path:-"$rvm_path/docs"}" ]] then mkdir -p "${rvm_docs_path:-"$rvm_path/docs"}/rdoc" "${rvm_docs_path:-"$rvm_path/docs"}/yard" fi usage() { printf "%b" " Usage: rvm docs {open,generate,generate-ri,generate-rdoc} " return 0 } open_docs() { if [[ -s "${rvm_docs_path:-"$rvm_path/docs"}/$rvm_docs_ruby_string/$rvm_docs_type/index.html" ]] then if [[ "${DESKTOP_SESSION}" == "gnome" ]] && builtin command -v gnome-open >/dev/null then gnome-open "${rvm_docs_path:-"$rvm_path/docs"}/$rvm_docs_ruby_string/$rvm_docs_type/index.html" &>/dev/null elif [[ -n "${XDG_SESSION_COOKIE}" || -n "${XDG_SESSION_ID}" ]] && builtin command -v xdg-open >/dev/null then xdg-open "${rvm_docs_path:-"$rvm_path/docs"}/$rvm_docs_ruby_string/$rvm_docs_type/index.html" &>/dev/null elif builtin command -v open >/dev/null then open "${rvm_docs_path:-"$rvm_path/docs"}/$rvm_docs_ruby_string/$rvm_docs_type/index.html" else rvm_error "None of open, xdg-open or gnome-open were found, in order to open the docs one of these two are required. \n(OR you can let me know how else to open the html in your browser from comand line on your OS :) )" fi else rvm_error "$rvm_docs_type docs are missing, perhaps run 'rvm docs generate' first?" fi } generate_ri() { # Generate ri docs ( builtin cd "${rvm_src_path}/$rvm_docs_ruby_string/" rvm_log "Generating ri documentation, be aware that this could take a *long* time, and depends heavily on your system resources..." rvm_log "( Errors will be logged to ${rvm_log_path}/$rvm_docs_ruby_string/docs.log )" rdoc -a --ri-site > /dev/null 2>> ${rvm_log_path}/$rvm_docs_ruby_string/docs.log ) } generate_rdoc() { ( builtin cd "${rvm_src_path}/$rvm_docs_ruby_string/" __rvm_rm_rf "${rvm_docs_path:-"$rvm_path/docs"}/$rvm_docs_ruby_string/$rvm_docs_type/" rvm_log "Generating rdoc documentation, be aware that this could take a *long* time, and depends heavily on your system resources..." rvm_log "( Errors will be logged to ${rvm_log_path}/$rvm_docs_ruby_string/docs.log )" if gem list | GREP_OPTIONS="" \grep ^hanna >/dev/null 2>&1 then hanna -o "${rvm_docs_path:-"$rvm_path/docs"}/$rvm_docs_ruby_string/$rvm_docs_type" --inline-source --line-numbers -fmt=html > /dev/null 2>> "${rvm_log_path}/$rvm_docs_ruby_string/docs.log" else rdoc -a -o "${rvm_docs_path:-"$rvm_path/docs"}/$rvm_docs_ruby_string/$rvm_docs_type" > /dev/null 2>> "${rvm_log_path}/$rvm_docs_ruby_string/docs.log" fi ) } args=($*) action="${args[0]}" args=($(echo ${args[@]:1})) # Strip trailing / leading / extra spacing. case "$action" in generate) generate_ri generate_rdoc ;; open) open_docs generate-ri) generate_ri generate-rdoc) generate_rdoc help) usage *) usage ; exit 1 esac exit $? ;; ;; ;; ;; ;; 1.18.9. cron #!/usr/bin/env bash source "$rvm_scripts_path/base" # Add rvm variables on the beginning of crontab __rvm_cron_setup() { { echo "#sm start rvm" rvm env --cron echo "#sm end rvm" __sm.cron.show | __sm.filter.remove.group "^#sm start rvm$" "^#sm end rvm$" } | crontab } __rvm_cron_remove() { __sm.cron.show | __sm.filter.remove.group "^#sm start rvm$" "^#sm end rvm$" | crontab } __rvm_cron_command() { typeset v schedule schedule="$1" shift || { rvm_error "Schedule not given, example: rvm cron command \"@daily\" rake calculate:stats" rvm_info "Refer to \`man 5 crontab\` for format of the scheduling definition." exit 1 } [[ -n "$1" ]] || { rvm_error "Command not given, example: rvm cron command \"@daily\" rake calculate:stats" exit 2 } { __sm.cron.show printf "%b" "${schedule} $(which rvm) in \"$PWD\" do" for v in "$@" do printf "%b" " \"$v\"" done printf "\n" } | crontab } __sm.cron.show() { EDITOR=cat crontab -e 2>/dev/null } __sm.filter.remove.group() { awk 'BEGIN{in_group=0} /'"$1"'/ {in_group=1} in_group==0 {print} /'"$2"'/ {in_group=0}' } __rvm_cron_help() { cat "${rvm_help_path}/cron" } action="${1:-}" shift case "$action" in setup|remove|help) __rvm_cron_$action ;; command) __rvm_cron_$action "$@" ;; *) __rvm_cron_help ; exit 1 ;; esac 1.18.10. current #!/usr/bin/env bash if [[ "$rvm_trace_flag" -eq 2 ]] ; then set -x ; export rvm_trace_flag ; fi source "$rvm_scripts_path/base" printf "%b" "$(__rvm_env_string)\n" exit 0 1.18.11. group #!/usr/bin/env bash source "$rvm_scripts_path/base" source "$rvm_scripts_path/version" source "$rvm_scripts_path/functions/group" group_add() { for user in "${users[@]}" do printf "%b" "Ensuring '$user' is in group '$rvm_group_name'\n" add_user_to_rvm_group $user done } group_remove() { : } group_help args=($*) action="${users[$__array_start]}" users[$__array_start]="" users=(${args[@]}) true "${rvm_group_name:=rvm}" if (( UID > 0 )) then rvm_log "rvm group must be run as root." exit 1 fi case "$action" in add) group_add ;; rm|remove) group_remove ;; help) get_help true ;; *) false ;; esac exit $? 1.18.12. list #!/usr/bin/env bash rvm_base_except="selector" source "$rvm_scripts_path/base" usage() { printf "%b" " Usage: rvm list [action] Actions: {help,known,gemsets,default [string],rubies,strings,known_strings,ruby_svn_tags} " return 0 } list_gemsets() { typeset all_rubies version versions ruby_version_name current_ruby selected system_ruby system_version string binary if [[ "${1:-""}" == "strings" ]] then list_gemset_strings return 0 fi current_ruby="$(__rvm_env_string)" all_rubies="$(list_strings | sort)" printf "%b" "\nrvm gemsets\n" versions=($( builtin cd "${rvm_gems_path:-"$rvm_path/gems"}/" find . -maxdepth 1 -mindepth 1 -type d -print 2> /dev/null | \ awk '/[a-z]*-.*/ {print $NF}' | sort )) for version in "${versions[@]//.\/}" do ruby_version_name="$(echo "$version" | awk -F"${rvm_gemset_separator:-"@"}" '{print $1}')" if [[ "$all_rubies" != *"$ruby_version_name"* ]] then continue fi if printf "%b" "$version" | GREP_OPTIONS="" \grep '^jruby-' >/dev/null 2>&1 then string="[ $("$rvm_rubies_path/$ruby_version_name/bin/ruby" -v | awk '{print $NF}' | sed -e 's/\[//' -e 's/\]//') ]" elif [[ -n "$(echo then string="[ x86_64 else string="[ $(file /ppc/ {print "ppc"}' | fi "$version" | awk '/^maglev-|^macruby-/')" ]] ]" "$rvm_rubies_path/$ruby_version_name/bin/ruby" | awk '/x86.64/ {print "x86_64"} /386/ {print "i386"} \tr "\n" ' ')]" printf "%b" "\n" if [[ "$version" == "$current_ruby" ]] then printf "%b" "=> " else printf "%b" " " fi if rvm_pretty_print stdout then printf "%b" "${rvm_notify_clr:-}$version${rvm_reset_clr:-} $string" else printf "%b" "$version $string" fi done if [[ -f "$rvm_path/config/default" && -s "$rvm_path/config/default" ]] then version=$( GREP_OPTIONS="" \grep 'MY_RUBY_HOME' "$rvm_path/config/default" | head -1 | awk -F"'" '{print $2}' | xargs basename -) if [[ -n "$version" ]] then printf "%b" "\nDefault Ruby (for new shells)\n" string="[ $(file "$rvm_rubies_path/$version/bin/ruby" | awk '/x86.64/ {print "x86_64"} /386/ {print "i386"} /ppc/ {print "ppc"}' | \tr "\n" ' ')]" if rvm_pretty_print stdout then printf "%b" "\n ${rvm_notify_clr:-}$version${rvm_reset_clr:-} $string\n" else printf "%b" "\n $version $string\n" fi fi fi printf "%b" "\n\n" return 0 } list_default() { typeset version string if [[ "${args[0]:-""}" == "string" ]] then "$rvm_scripts_path/alias" show default 2>/dev/null | \ awk -F"${rvm_gemset_separator:-"@"}" '{print $1}' | \ xargs basename -else if [[ -L "$rvm_rubies_path/default" ]] then version=$( "$rvm_scripts_path/alias" show default 2>/dev/null | \ awk -F"${rvm_gemset_separator:-"@"}" '{print $1}' | \ xargs basename -) if [[ -n "$version" ]] then printf "%b" "\nDefault Ruby (for new shells)\n" string="[ $(file "$rvm_rubies_path/$version/bin/ruby" | awk '/x86.64/ {print "x86_64"} /386/ {print "i386"} /ppc/ {print "ppc"}' | \tr "\n" ' ')]" if rvm_pretty_print stdout then printf "%b" "\n ${rvm_notify_clr:-}$version${rvm_reset_clr:-} $string\n" else printf "%b" "\n $version $string\n" fi fi fi fi printf "%b" "\n" return 0 } list_ruby_svn_tags() { typeset prefix tag while read -r tag do prefix="$( echo ${tag/\//} | \ sed 's#^v1_##' | \ awk -F'_' '{print "(ruby-)1."$1"."$2}' | \ sed 's#p$##' )" echo "${prefix}-t${tag/\//}" done < <(svn list http://svn.ruby-lang.org/repos/ruby/tags/ | \ awk '/^v1_[8|9]/') return 0 } # Query for valid rvm ruby strings # This is meant to be used with scripting. list_strings() { ( builtin cd "$rvm_rubies_path" find . -maxdepth 1 -mindepth 1 -type d | sed -e 's#./##g' ) return $? } # This is meant to be used with scripting. list_gemset_strings() { typeset all_rubies ruby_name gemset gemsets all_rubies="$(list_strings | sort)" gemsets=($( builtin cd "${rvm_gems_path:-"$rvm_path/gems"}" find . -maxdepth 1 -mindepth 1 -type d 2>/dev/null | \ xargs -n1 basename -- | \ GREP_OPTIONS="" \grep -v '^\(@\|doc$\|cache$\|system$\)' | sort )) for gemset in "${gemsets[@]//.\/}" do ruby_name="${gemset//${rvm_gemset_separator:-"@"}*}" if [[ "$all_rubies" != *"$ruby_name"* ]] then continue fi echo "$gemset" done return 0 } # This is meant to be used with scripting. list_known_strings() { sed -e 's/#.*$//g' -e 's#\[##g' -e 's#\]##g' < "$rvm_path/config/known" | \ sort -r | uniq return $? } list_known() { if [[ "${1:-""}" == "strings" ]] then list_known_strings return 0 fi if [[ -t 0 ]] then __rvm_pager_or_cat_v "$rvm_path/config/known" else cat "$rvm_path/config/known" fi return $? } list_rubies_strings() { ( builtin cd "$rvm_rubies_path" find -maxdepth 0 -type d | tail -n+2 | xargs -n1 basename -- | ) __rvm_strip return $? } list_rubies() { typeset current_ruby rubies version selected system_ruby system_version \ default_ruby string binary if [[ "${1:-""}" == "strings" ]] then list_rubies_strings return 0 fi current_ruby="$( __rvm_env_string )" current_ruby="${current_ruby%${rvm_gemset_separator:-"@"}*}" default_ruby="$( "$rvm_scripts_path/alias" show default 2>/dev/null )" default_ruby="${default_ruby%${rvm_gemset_separator:-"@"}*}" printf "%b" "\nrvm rubies\n\n" rubies=($( builtin cd "$rvm_rubies_path/" find . -maxdepth 1 -mindepth 1 -type d 2> /dev/null | sort )) for version in "${rubies[@]//.\/}" do if [[ ! -x "$rvm_rubies_path/$version/bin/ruby" ]] then continue fi if [[ "$version" = "$current_ruby" && "$version" = "$default_ruby" ]] then printf "%b" "=* " elif [[ "$version" = "$current_ruby" ]] then printf "%b" "=> " elif [[ "$version" = "$default_ruby" ]] then printf "%b" " * " else printf "%b" " " fi if [[ ! -z "$(echo "$version" | awk '/^maglev-|^macruby-/')" ]] ; then string="[ x86_64 ]" else string="[ $(. $rvm_rubies_path/$version/config ; echo $target_cpu) ]" fi if rvm_pretty_print stdout then printf "%b" "${rvm_notify_clr:-}$version${rvm_reset_clr:-} $string" else printf "%b" "$version $string" fi printf "%b" "\n" done if (( ${#rubies[@]} == 0 )) then printf "%b" " # No rvm rubies installed yet. Try 'rvm help install'. " else if [[ -z "${default_ruby}" ]] then printf "%b" " # Default ruby not set. Try 'rvm alias create default <ruby>'. " fi printf "%b" " # => - current # =* - current && default # * - default " fi printf "%b" "\n" return 0 } # List all rvm installed rubies, default ruby and system ruby. # Display the rubies, indicate their architecture and indicate which is currently used. # This is not meant to be used with scripting. This is for interactive mode usage only. args=($*) action="${args[0]:-""}" args=${args[@]:1} # Strip trailing / leading / extra spacing. if [[ -z "$action" ]] then list_rubies exit 0 fi case "$action" in known) list_known known_strings) list_known_strings gemsets) list_gemsets "$args" default) list_default rubies) list_rubies "$args" strings) list_strings ruby_svn_tags) list_ruby_svn_tags help) usage *) usage ; exit 1 esac exit $? ;; ;; ;; ;; ;; ;; ;; ;; ;; 1.18.13. install #!/usr/bin/env bash export PS4 PATH PS4="+ \${BASH_SOURCE##\${rvm_path:-}} : \${FUNCNAME[0]:+\${FUNCNAME[0]}()} \${LINENO} > " set -o errtrace if [[ "$*" =~ --trace ]] || (( ${rvm_trace_flag:-0} > 0 )) then # Tracing, if asked for. set -o xtrace export rvm_trace_flag=1 fi #Handle Solaris Hosts if [[ "$(uname -s)" == "SunOS" ]] then PATH="/usr/gnu/bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH" elif [[ "$(uname)" == "OpenBSD" ]] then # don't touch PATH, true else PATH="/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/sbin:$PATH" fi if [[ -n "${rvm_user_path_prefix:-}" ]] then PATH="${rvm_user_path_prefix}:$PATH" fi shopt -s extglob source "$PWD/scripts/functions/installer" # source "$PWD/scripts/rvm" # # RVM Installer # install_setup true ${DESTDIR:=} # Parse RVM Installer CLI arguments. while (( $# > 0 )) do token="$1" shift case "$token" in (--auto) rvm_auto_flag=1 ;; (--without-gems=*) export rvm_without_gems="${token#--without-gems=}" ;; (--path) rvm_path="$1" shift ;; (--version) rvm_path="${PWD%%+(\/)}" __rvm_version unset rvm_path exit ;; (--debug) export rvm_debug_flag=1 set -o verbose ;; (--trace) set -o xtrace export rvm_trace_flag=1 echo "$@" env | GREP_OPTIONS="" \grep '^rvm_' export PS4="+ \${BASH_SOURCE##\${rvm_path:-}} : \${FUNCNAME[0]:+\${FUNCNAME[0]}()} ;; (--help) install_usage exit 0 ;; (*) echo "Unrecognized option: $token" install_usage exit 1 ;; esac done if [[ -n "${DESTDIR}" ]] then rvm_prefix="${DESTDIR}" fi \${LINENO} > " determine_install_path determine_install_or_upgrade if [[ -z "${rvm_path:-}" ]] then echo "ERROR: rvm_path is empty, halting installation." exit 1 fi export rvm_prefix rvm_path rvm_debug_flag rvm_trace_flag create_install_paths print_install_header configure_installation cleanse_old_entities install_rvm_files install_rvm_hooks ensure_scripts_are_executable setup_configuration_files install_binscripts install_gemsets install_patchsets cleanse_old_environments migrate_old_gemsets migrate_defaults correct_binary_permissions install_man_pages root_canal setup_rvmrc setup_user_profile record_ruby_configs update_gemsets_install_rvm cleanup_tmp_files display_notes display_thank_you record_installation_time 1.18.14. env #!/usr/bin/env bash source "$rvm_scripts_path/base" environment_file_path="$rvm_environments_path/$(__rvm_env_string)" # Echo the path or environment file. if [[ "$rvm_path_flag" == "1" || "$*" =~ "--path" ]] then echo "$environment_file_path" elif [[ "$rvm_cron_flag" == "1" || "$*" =~ "--cron" ]] then cat "$environment_file_path" | GREP_OPTIONS="" \grep -Eo "[^ ]+=[^;]+" | sed -e 's/\$PATH/'"${PATH//\//\/}"'/' -e 's/\${PATH}/'"${PATH//\//\/}"'/' else cat "$environment_file_path" fi 1.18.15. match #!/usr/bin/env bash [[ -n "$1" && -n "$2" && -n "$(echo "$1" | awk "/${2//\//\/}/")" ]] || exit 1 1.18.16. rvm-install #!/usr/bin/env bash export PS4 PATH PS4="+ \${BASH_SOURCE##\${rvm_path:-}} : \${FUNCNAME[0]:+\${FUNCNAME[0]}()} \${LINENO} > " set -o errtrace if [[ "$*" =~ --trace ]] || (( ${rvm_trace_flag:-0} > 0 )) then # Tracing, if asked for. set -o xtrace export rvm_trace_flag=1 fi #Handle Solaris Hosts if [[ "$(uname -s)" == "SunOS" ]] then PATH="/usr/gnu/bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH" else PATH="/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/sbin:$PATH" fi if [[ -n "${rvm_user_path_prefix:-}" ]] then PATH="${rvm_user_path_prefix}:$PATH" fi shopt -s extglob source "$PWD/scripts/functions/installer" # source "$PWD/scripts/rvm" # # RVM Installer # install_setup true ${DESTDIR:=} # Parse RVM Installer CLI arguments. while (( $# > 0 )) do token="$1" shift case "$token" in (--auto) rvm_auto_flag=1 ;; (--path) rvm_path="$1" shift ;; (--version) rvm_path="${PWD%%+(\/)}" __rvm_version unset rvm_path exit ;; (--debug) export rvm_debug_flag=1 set -o verbose ;; (--trace) set -o xtrace export rvm_trace_flag=1 echo "$@" env | GREP_OPTIONS="" \grep '^rvm_' export PS4="+ \${BASH_SOURCE##\${rvm_path:-}} : \${FUNCNAME[0]:+\${FUNCNAME[0]}()} ;; (--help) install_usage exit 0 ;; (*) echo "Unrecognized option: $token" install_usage exit 1 ;; esac done if [[ -n "${DESTDIR}" ]] then rvm_prefix="${DESTDIR}" fi determine_install_path determine_install_or_upgrade if [[ -z "${rvm_path:-}" ]] then echo "ERROR: rvm_path is empty, halting installation." \${LINENO} > " exit 1 fi export rvm_prefix rvm_path rvm_debug_flag rvm_trace_flag create_install_paths print_install_header configure_installation cleanse_old_entities install_rvm_files install_rvm_hooks ensure_scripts_are_executable setup_configuration_files install_binscripts automatic_profile_setup install_gemsets install_patchsets cleanse_old_environments migrate_old_gemsets migrate_defaults correct_binary_permissions install_man_pages root_canal setup_rvmrc setup_user_profile record_ruby_configs cleanup_tmp_files display_thank_you display_notes display_requirements 1.18.17. hash #!/usr/bin/env bash # # # # # # # # The idea is that we emulate a hash using two methods The first method is providing functions by sourcing this file The second method is where this script is called directly, we then provide functionality of a file based hash if [[ "$rvm_trace_flag" -eq 2 ]] ; then set -x ; export rvm_trace_flag ; fi [[ -z "${ZSH_VERSION:-}" ]] ; array_start=$? hash() { hash_name=$1 ; hash_key=$2 ; hash_value=$3 eval "_hash_${hash_name}_keys=\${_hash_${hash_name}_keys:-()} ; _hash_${hash_name}_values=\${_hash_${hash_name}_values:()}" if [[ -z "$hash_value" ]] ; then eval "length=\${#_hash_${hash_name}_keys[@]}" for (( index=$__array_start ; index < $length; index++ )) ; do eval "key=\"\${_hash_${hash_name}_keys[$index]}\"" if [[ "$hash_key" == "$key" ]] ; then eval "echo -n \${_hash_${hash_name}_values[$index]}" break fi done else eval "index=\$((\${#_hash_${hash_name}_keys[*]} + $__array_start))" eval "_hash_${hash_name}_keys[$index]=\"$hash_key\"" eval "_hash_${hash_name}_values[$index]=\"$hash_value\"" fi } 1.18.18. version #!/usr/bin/env bash __rvm_meta() { rvm_meta_author="Wayne E. Seguin" rvm_meta_author_email="wayneeseguin@gmail.com" rvm_meta_authors=( "Wayne E. Seguin <wayneeseguin@gmail.com>" "Michal Papis <mpapis@gmail.com>" ) rvm_meta_website="https://rvm.io/" rvm_meta_version="${rvm_version}" } __rvm_version() { __rvm_meta typeset IFS release IFS=':' rvm_meta_authors="${rvm_meta_authors[*]}" rvm_meta_authors="${rvm_meta_authors//:/, }" echo -e "\nrvm ${rvm_meta_version} by ${rvm_meta_authors} [${rvm_meta_website}]\n" } 1.18.19. pkg #!/usr/bin/env bash if (( ${rvm_trace_flag:=0} == 2 )) then set -x export rvm_trace_flag fi rvm_base_except="selector" source source source source "$rvm_scripts_path/base" "$rvm_scripts_path/functions/build" "$rvm_scripts_path/functions/db" "$rvm_scripts_path/functions/pkg" __rvm_setup_compile_environment set +o errexit # Tools to make managing ruby dependencies inside of rvm easier. args=($*) action="${args[0]:-""}" library="${args[1]:-""}" args="$(echo ${args[@]:2})" if [[ -n "$library" ]] then case $library in readline|iconv|curl|openssl|zlib|autoconf|ncurses|pkgconfig|gettext|glib|mono|llvm|libxml2|libxslt|libyaml) ${library} ;; ree_dependencies) for i in zlib ncurses readline openssl iconv; do ${i} reset done ;; *) rvm_error "Package '${library}' is unknown." ;; esac exit $? else rvm_log "\nUsage:\n 'rvm pkg {install,uninstall} {readline,iconv,curl,openssl,zlib,autoconf,ncurses,pkgconfig,gettext,glib,mono,llvm,libxml2,libxslt,libyaml}'\n 'ree_dependencies' installs zlib, ncurses, readline, openssl and iconv in this order.\n still need to add ' --with-readline-dir=\$rvm_usr_path --with-iconv-dir=\$rvm_usr_path --with-zlib-dir=\$rvm_usr_path -with-openssl-dir=\$rvm_usr_path' to 'rvm install ree'\n" exit 1 fi 1.18.20. md5 #!/usr/bin/env bash variable_is_nonempty() { typeset _variable _variable="${1:-}" if [[ -n "${_variable}" ]] then eval "[[ -n \"\${${_variable}:-}\" ]]" || return $? else fail "Cannot check if variable is nonempty; no variable was given." fi } command_exists() { typeset _name _name="${1:-}" if variable_is_nonempty _name then builtin command -v "${_name}" > /dev/null 2>&1 || return 1 else fail "Cannot test if command exists; no command name was given." fi } if (( ${rvm_trace_flag:=0} == 2 )) then set -x export rvm_trace_flag fi _archive="${1}" shift || fail "archive name not given in first param" md5="${1}" shift || fail "md5 value not given in second param" # Swiped from BDSM if command_exists md5 then archive_md5=$(md5 -q "${_archive}") elif command_exists md5sum then archive_md5="$(md5sum "${_archive}")" archive_md5="${archive_md5%% *}" else for _path in /usr/gnu/bin /sbin /bin /usr/bin /usr/sbin do if [[ -x "${_path}/md5" ]] then archive_md5=$(${_path}/md5 -q "${_archive}") elif [[ -x "${_path}/md5sum" ]] then archive_md5="$(${_path}/md5sum "${_archive}")" archive_md5="${archive_md5%% *}" fi done fi [[ "${archive_md5}" == "${md5}" ]] || exit $? 1.18.21. rvm #!/usr/bin/env bash # rvm : Ruby enVironment Manager # https://rvm.io # https://github.com/wayneeseguin/rvm # Do not allow sourcing RVM in `sh` - it's not supported # return 0 to exit from sourcing this script without breaking sh [[ ":$SHELLOPTS:" =~ ":posix:" ]] && return 0 || true # TODO: Alter the variable names to make sense \export HOME rvm_prefix rvm_user_install_flag rvm_path HOME="${HOME%%+(\/)}" # Remove trailing slashes if they exist on HOME : rvm_stored_umask:${rvm_stored_umask:=$(umask)} if (( ${rvm_ignore_rvmrc:=0} == 0 )) then rvm_rvmrc_files=("/etc/rvmrc" "$HOME/.rvmrc") if [[ -n "${rvm_prefix:-}" ]] && ! [[ "$HOME/.rvmrc" -ef "${rvm_prefix}/.rvmrc" ]] then rvm_rvmrc_files+=( "${rvm_prefix}/.rvmrc" ) fi for rvmrc in "${rvm_rvmrc_files[@]}" do if [[ -f "$rvmrc" ]] then if GREP_OPTIONS="" \grep '^\s*rvm .*$' "$rvmrc" >/dev/null 2>&1 then printf "%b" " Error: $rvmrc is for rvm settings only. rvm CLI may NOT be called from within $rvmrc. Skipping the loading of $rvmrc" return 1 else source "$rvmrc" fi fi done unset rvm_rvmrc_files fi # detect rvm_path if not set if [[ -z "${rvm_path:-}" ]] then if (( UID == 0 )) then if (( ${rvm_user_install_flag:-0} == 0 )) then rvm_user_install_flag=0 rvm_prefix="/usr/local" rvm_path="${rvm_prefix}/rvm" else rvm_user_install_flag=1 rvm_prefix="$HOME" rvm_path="${rvm_prefix}/.rvm" fi else if [[ -d "$HOME/.rvm" && -s "$HOME/.rvm/scripts/rvm" ]] then rvm_user_install_flag=1 rvm_prefix="$HOME" rvm_path="${rvm_prefix}/.rvm" else rvm_user_install_flag=0 rvm_prefix="/usr/local" rvm_path="${rvm_prefix}/rvm" fi fi else # remove trailing slashes, btw. %%/ <- does not work as expected rvm_path="${rvm_path%%+(\/)}" fi # guess rvm_prefix if not set if [[ -z "${rvm_prefix}" ]] then rvm_prefix=$( dirname $rvm_path ) fi # guess rvm_user_install_flag if not set if [[ -z "${rvm_user_install_flag}" ]] then if [[ "${rvm_prefix}" == "${HOME}" ]] then rvm_user_install_flag=1 else rvm_user_install_flag=0 fi fi export rvm_loaded_flag if [[ -n "${BASH_VERSION:-}" || -n "${ZSH_VERSION:-}" ]] && typeset -f rvm >/dev/null 2>&1 then rvm_loaded_flag=1 else rvm_loaded_flag=0 fi if (( ${rvm_loaded_flag:=0} == 0 )) || (( ${rvm_reload_flag:=0} == 1 )) then if [[ -n "${rvm_path}" && -d "$rvm_path" ]] then true ${rvm_scripts_path:="$rvm_path/scripts"} if [[ -f "$rvm_scripts_path/base" ]] then source "$rvm_scripts_path/base" else printf "%b" "WARNING: Could not source '$rvm_scripts_path/base' as file does not exist. RVM will likely not work as expected.\n" fi __rvm_ensure_is_a_function __rvm_setup export rvm_version rvm_version="$(cat "$rvm_path/VERSION") ($(cat "$rvm_path/RELEASE" 2>/dev/null))" alias rvm-restart="rvm_reload_flag=1 source '${rvm_scripts_path:-${rvm_path}/scripts}/rvm'" if ! builtin command -v ruby >/dev/null 2>&1 || builtin command -v ruby | GREP_OPTIONS="" \grep -v "${rvm_path}" >/dev/null || builtin command -v ruby | GREP_OPTIONS="" \grep "${rvm_path}/bin/ruby$" >/dev/null then if [[ -s "$rvm_environments_path/default" ]] then source "$rvm_environments_path/default" elif [[ -s "$rvm_path/environments/default" ]] then source "$rvm_path/environments/default" fi fi # Makes sure rvm_bin_path is in PATH atleast once. __rvm_conditionally_add_bin_path if (( ${rvm_reload_flag:=0} == 1 )) then [[ "${rvm_auto_reload_flag:-0}" == 2 ]] || printf "%b" 'RVM reloaded!\n' # make sure we clean env on reload __rvm_env_loaded=1 unset __rvm_project_rvmrc_lock fi rvm_loaded_flag=1 else printf "%b" "\n\$rvm_path ($rvm_path) does not exist." fi unset rvm_prefix_needs_trailing_slash rvm_gems_cache_path \ rvm_gems_path rvm_project_rvmrc_default rvm_gemset_separator rvm_reload_flag else source "${rvm_scripts_path:="$rvm_path/scripts"}/initialize" __rvm_setup fi if [[ -t 0 && ${rvm_project_rvmrc:-1} -gt 0 ]] && rvm_is_a_shell_function no_warning && ! __function_on_stack __rvm_project_rvmrc && typeset -f __rvm_project_rvmrc >/dev/null 2>&1 then # Reload the rvmrc, use promptless ensuring shell processes does not # prompt if .rvmrc trust value is not stored. rvm_promptless=1 __rvm_project_rvmrc rvm_hook=after_cd source "${rvm_scripts_path:-${rvm_path}/scripts}/hook" fi __rvm_teardown 1.18.22. aliases alias alias alias alias rubydo="rvm ruby" gemdo="rvm gem" rakedo="rvm rake" multiruby="rvm ruby" 1.18.23. default #!/usr/bin/env bash source "$rvm_scripts_path/base" rvm_ruby_gem_home="${rvm_ruby_gem_home:-$GEM_HOME}" if [[ ! -d "$rvm_ruby_gem_home" ]] && builtin command -v gem > /dev/null 2>&1; then rvm_ruby_gem_home="$(gem env home)" ; fi usage() { printf "%b" " Usage: rvm default [ruby] [environment_id] Action: {import,export,create,copy,empty,delete,name,dir,list,gemdir,install,pristine,clear,use,update,globalcache} Description: Commands for working with and manipulating gemsets within RVM. Examples: rvm default rvm default rvm default rvm default rvm default rvm default 1.9.2 list 1.9.2 1.9.2 1.9.2-p0 clear 1.9.2 clear # # # # # # *uses* the default ruby Sets the 'global' default to 1.9.2 displays the environment_id for the current 1.9.2 default sets the default for 'rvm 1.9.2' to p0 clears the set default for 1.9.2 removes the current global default " } default_list() { : } default_clear() { : } args=($*) action="${args[0]}" args=${args[@]:1} if [[ "list" == "$action" ]] ; then default_list elif [[ "clear" == "$action" ]] ; then default_clear elif [[ "help" == "$action" ]] ; then usage ; exit 0 else usage ; exit 1 fi exit $? 1.18.24. notes #!/usr/bin/env bash if ! typeset -f rvm_pretty_print >/dev/null 2>&1 then source "${rvm_scripts_path:-"$rvm_path/scripts"}/functions/logging" fi if [[ "$1" == "initial" ]] then notes_type=Upgrade PAGER=cat new_notes() { typeset file file="$rvm_path/config/displayed-notes.txt" rm -f "${file}" tee "${file}" > /dev/null } elif [[ "$1" == "upgrade" ]] then notes_type=Upgrade PAGER=cat new_notes() { typeset file file="$rvm_path/config/displayed-notes.txt" touch "${file}" tee "${file}.new" | ( diff --normal - "${file}" && \ printf " * No new notes to display.\n" >&2 || true ) | sed '/^[^<]/ d ; s/^< //' mv -f "${file}.new" "${file}" } else notes_type=Installation new_notes() { cat } fi if [[ "$1" == "upgrade" ]] then printf "%b" " $notes_type Notes: " fi # this block groups generated and static notes, # to add generated msgs put them bellow in code # for general messages put them in help/upgrade-notes.txt { if [[ -z "$1" ]] then printf "%b" " $notes_type Notes: " fi if [[ "$rvm_path" == "/usr/local/rvm" ]] || (( UID == 0 )) then printf "%b" " * Please do NOT forget to add your users to the 'rvm' group. The installer no longer auto-adds root or users to the rvm group. Admins must do this. Also, please note that group memberships are ONLY evaluated at login time. This means that users must log out then back in before group membership takes effect! " fi : \ rvm_scripts_path:${rvm_scripts_path:-$rvm_path/scripts}: cat "$rvm_path/help/upgrade-notes.txt" | sed \ -e "s/\${SHELL}/${SHELL//\//\/}/g" \ -e "s/\${rvm_scripts_path}/${rvm_scripts_path//\//\/}/g" printf "\n" if [[ -f /etc/profile.d/rvm.sh ]] && ! GREP_OPTIONS="" \grep rvm_stored_umask /etc/profile.d/rvm.sh >/dev/null then printf "%b" " * WARNING: your RVM loading script \`/etc/profile.d/rvm.sh\` is deprecated and causes you to have \`umask g+w\` set in your shell, run \`rvm get head --auto\` again to fix your scripts. " fi if [[ "$rvm_path" == "/usr/share/ruby-rvm" ]] then printf "%b" " * WARNING: You are using apt-get broken RVM, you should now: sudo apt-get --purge remove ruby-rvm sudo rm -rf /usr/share/ruby-rvm /etc/rvmrc /etc/profile.d/rvm.sh open new terminal and validate environment is clean from old rvm settings: env | GREP_OPTIONS="" \grep rvm install RVM: curl -L get.rvm.io | bash -s stable " fi if [[ -n "${RUBYOPT:-""}" ]] then printf "%b" " * WARNING: You have RUBYOPT set in your current environment. This may cause rubies to not work as you expect them to as it is not supported by all of them If errors show up, please try unsetting RUBYOPT first. " fi if [[ -f ~/.profile ]] && ! [[ "$rvm_path" == "/usr/local/rvm" || $UID == 0 ]] then printf "%b" " * WARNING: You're using ~/.profile, make sure you load it, add the following line to ~/.bash_profile if it exists otherwise add it to ~/.bash_login: source ~/.profile " fi if [[ -n "${ZSH_VERSION:-}" ]] && (( 65536 * ${ZSH_VERSION:0:1} + 256 * ${ZSH_VERSION:2:1} + ${ZSH_VERSION:4} != 262924 )) then printf "%b" " * WARNING: ZSH 4.3.12 is recommended, you have $ZSH_VERSION. " fi if [[ -n "${GEM_HOME:-}" ]] && ! [[ "${GEM_HOME}" =~ "$rvm_path/" ]] then printf "%b" " * WARNING: you have GEM_HOME=\"${GEM_HOME}\" this is conflicting with RVM, make sure to: unset GEM_HOME " fi } | new_notes | eval "${PAGER:-cat}" printf "%b" \ " # RVM: Shell scripts enabling management of multiple ruby environments. # RTFM: https://rvm.io/ # HELP: http://webchat.freenode.net/?channels=rvm (#rvm on irc.freenode.net) # Cheatsheet: http://cheat.errtheblog.com/s/rvm/ # Screencast: http://screencasts.org/episodes/how-to-use-rvm " rvm_log " # In case of any issues read output of 'rvm requirements' and/or 'rvm notes' " 1.18.25. migrate #!/usr/bin/env bash unset GREP_OPTIONS source "$rvm_scripts_path/base" usage() { printf "%b" " Usage: rvm migrate {source-ruby} {destination-ruby} Description: Moves all gemsets from {source-ruby} ruby to {destination-ruby}. " >&2 } confirm() { typeset confirmation_response printf "%b" "$1 (Y/n): " read -r confirmation_response [[ -z "$confirmation_response" ]] || echo "$confirmation_response" | GREP_OPTIONS="" \grep -i '^y' >/dev/null 2>&1 } die_with_error() { rvm_error "$1" exit "${2:-1}" } expand_ruby_name() { "$rvm_scripts_path/tools" strings "$1" | awk -F"${rvm_gemset_separator:-"@"}" '{print $1}' } migrate_rubies() { typeset origin_gemset destination_gemset gemset_name migrate_ruby_name \ migrate_alias_name migrate_new_alias_name binaries origin_wrappers_path \ full_bin_path expanded_symlink linked_binary_name new_wrapper_destination expanded_source="$(expand_ruby_name "$source_ruby")" expanded_destination="$(expand_ruby_name "$destination_ruby")" if [[ -z "$expanded_source" ]] then die_with_error "Could not expand source ruby '$source_ruby'" elif [[ -z "$expanded_destination" ]] then die_with_error "Could not expand destination ruby '$destination_ruby'" elif [[ "$expanded_destination" == "$expanded_source" ]] then die_with_error "Source and Destination Ruby are the same ($expanded_destination)" elif [[ ! -d "$rvm_rubies_path/$expanded_source" ]] then die_with_error "Ruby '$expanded_source' is not installed - please install it first." elif [[ ! -d "$rvm_rubies_path/$expanded_destination" ]] then die_with_error "Ruby '$expanded_destination' is not installed - please install it first." fi echo "Are you sure you wish to MOVE gems from $expanded_source to $expanded_destination?" confirm "This will overwrite existing gems in $expanded_destination and remove them from $expanded_source" || return 1 echo "Moving gemsets..." while read -r origin_gemset do [[ "$origin_gemset" == "$expanded_source" || "$origin_gemset" == "${expanded_source}${rvm_gemset_separator:-"@"}"* ]] || continue destination_gemset="$expanded_destination" case "$origin_gemset" in *${rvm_gemset_separator:-@}*) gemset_name="${origin_gemset/*${rvm_gemset_separator:-"@"}/}" ;; esac if [[ -n "$gemset_name" ]] then destination_gemset="${destination_gemset}${rvm_gemset_separator:-"@"}${gemset_name}" fi echo "Moving $origin_gemset to $destination_gemset" __rvm_rm_rf "${rvm_gems_path:-"$rvm_path/gems"}/$destination_gemset" result="$?" [[ $result -gt 0 ]] && die_with_error "Unable to remove gem directory '${rvm_gems_path:"$rvm_path/gems"}/$destination_gemset'" "$result" mv "${rvm_gems_path:-"$rvm_path/gems"}/$origin_gemset" "${rvm_gems_path:-"$rvm_path/gems"}/$destination_gemset" result="$?" [[ $result -gt 0 ]] && die_with_error "Unable to move '${rvm_gems_path:-"$rvm_path/gems"}/$origin_gemset' to '${rvm_gems_path:-"$rvm_path/gems"}/$destination_gemset'" "$result" __rvm_run_with_env "gemset.pristine" "$destination_gemset" "rvm gemset pristine" "Making gemset $destination_gemset pristine." done < <("$rvm_scripts_path/list" gemsets strings | GREP_OPTIONS="" \grep "^$expanded_source") if confirm 'Do you wish to move over aliases?' then while read -r alias_pair do migrate_ruby_name="${alias_pair/*=/}" migrate_alias_name="${alias_pair/=*/}" if [[ "$migrate_ruby_name" == "$expanded_source" || \ "$migrate_ruby_name" == "${expanded_source}${rvm_gemset_separator:-"@"}"* ]] then migrate_new_alias_name="${migrate_ruby_name/$expanded_source/$expanded_destination}" echo "Updating alias $migrate_alias_name to point to $migrate_new_alias_name" "$rvm_scripts_path/alias" delete "$migrate_alias_name" >/dev/null 2>&1 "$rvm_scripts_path/alias" create "$migrate_alias_name" "$migrate_new_alias_name" >/dev/null 2>&1 fi done < "$rvm_path/config/alias" fi if confirm "Do you wish to move over wrappers?" then origin_wrappers_path="$rvm_wrappers_path/$expanded_source" binaries=($(cd "${rvm_bin_path}" ; find . -maxdepth 1 -mindepth 1 -type f)) for binary_name in "${binaries[@]//.\/}" do full_bin_path="${rvm_bin_path}/$binary_name" [[ -L "$full_bin_path" ]] || continue expanded_symlink="$(readlink "$full_bin_path")" [[ "$expanded_symlink" == "$origin_wrappers_path/"* ]] || continue linked_binary_name="$(basename "$expanded_symlink")" [[ "$binary_name" == "$linked_binary_name-$expanded_source" || "$binary_name" == "$expanded_source" ]] && continue new_wrapper_destination="${expanded_symlink/$expanded_source/$expanded_destination}" ln -sf "$new_wrapper_destination" "$full_bin_path" done fi if confirm "Do you also wish to completely remove $expanded_source (inc. archive)?" then __rvm_run_with_env "rvm.remove" "$expanded_source" "rvm remove $expanded_source --archive --gems" fi echo "Successfully migrated $expanded_source to $expanded_destination" } args=($*) source_ruby="${args[0]}" destination_ruby="${args[1]}" args="$(echo ${args[@]:2})" # Strip trailing / leading / extra spacing. if [[ -z "$source_ruby" || -z "$destination_ruby" ]]; then usage ; exit 1 fi source_ruby="$1"; shift destination_ruby="$1"; shift migrate_rubies 1.18.26. manage #!/usr/bin/env bash sys=$( uname -s ) if [[ "${sys}" == AIX ]] then name_opt=-name else name_opt=-iname fi original_ruby_version=${rvm_ruby_version:-""} original_ruby_string=${rvm_ruby_string:-""} source source source source source source source "$rvm_scripts_path/base" "$rvm_scripts_path/patches" "$rvm_scripts_path/functions/build" "$rvm_scripts_path/functions/pkg" "$rvm_scripts_path/functions/irbrc" "$rvm_scripts_path/functions/db" "$rvm_scripts_path/functions/manage/base" unset RUBYLIB RUBYOPT # Sanity check. args=($*) action="${args[0]:-""}" rubies_string="${args[1]:-""}" args="$(echo ${args[@]:2})" # Strip trailing / leading / extra spacing. binaries=() __rvm_manage_rubies exit $? # located in scripts/functions/manage/base 1.18.27. repair #!/usr/bin/env bash source "$rvm_scripts_path/base" usage() { printf "%b" " Usage: rvm repair [option] Options: wrappers symlinks environments archives gemsets all - Repair Repair Repair Repair Repair Repair wrappers symlinks environments archives gemsets all of the above " } repair_gemsets() { typeset directory directories rvm_log "Removing gemsets missing names or interpreters." ( builtin cd "${rvm_gems_path:-"rvm_path/gems"}" directories=( $( find . -mindepth 1 -maxdepth 1 -type d | GREP_OPTIONS="" \grep '@$' ) $( find . -mindepth 1 -maxdepth 1 -type d | GREP_OPTIONS="" \grep '^./@') ) for directory in "${directories[@]//.\/}" do __rvm_rm_rf "./$directory/" done ) rvm_log "Gemsets repaired." return 0 } repair_wrappers() { typeset wrapper_ruby_name rvm_log "Regenerating all wrappers..." while read -r wrapper_ruby_name do rvm_log "Regenerating wrappers for $wrapper_ruby_name" __rvm_run "wrappers.regenerate" "\"$rvm_scripts_path/wrapper\" '$wrapper_ruby_name'" done < <("$rvm_scripts_path/list" gemsets strings) rvm_log "Wrappers regenerated" return 0 } # Removes stale symlinks in $rvm_bin_path, likely # related to wrappers. repair_symlinks() { rvm_log "Repairing symlinks..." ( builtin cd "${rvm_bin_path}" for executable_name in $(\find \. -type l) do if [[ -e "$executable_name" || \ "$(readlink "$executable_name")" != "$rvm_wrappers_path/"* ]] then continue fi if [[ -f "$executable_name" ]] then rvm_log "removing stale symlink from $(basename "$executable_name")" \rm -f "$executable_name" fi done ) rvm_log "Symlinks repaired" } # Regenerates each symlink file. repair_environments() { typeset environment_name environments rvm_log "Regenerating environments..." environments=($(builtin cd "$rvm_environments_path" ; find . -maxdepth 1 -mindepth 1 -type f)) for environment_name in "${environments[@]//.\/}" do [[ -L "$rvm_environments_path/$environment_name" ]] && continue rvm_log "Regenerating environment file for '$environment_name'" [[ -f "$rvm_environments_path/$environment_name" ]] && \rm -f "$rvm_environments_path/$environment_name" ( source "$rvm_scripts_path/base" __rvm_become "$environment_name" __rvm_ensure_has_environment_files ) done rvm_log "Environments regenerated" } # Removes archives that have incorrect md5 sums. repair_archives() { typeset archive_file archives stored_md5sum rvm_log "Repairing archives..." archives=($(builtin cd "${rvm_archives_path}" ; find . -maxdepth 1 -mindepth 1 -type f)) for archive_file in "${archives[@]//.\/}" do [[ -f "${rvm_archives_path}/$archive_file" ]] || continue stored_md5sum="$("$rvm_scripts_path/db" "$rvm_path/config/md5" "$archive_file" | head -n1)" if [[ -z "$stored_md5sum" ]] then stored_md5sum="$("$rvm_scripts_path/db" "$rvm_user_path/md5" "$archive_file" | head -n1)" fi if [[ -n "$stored_md5sum" ]] then if ! "$rvm_scripts_path/md5" "${rvm_archives_path}/$archive_file" "$stored_md5sum" then rvm_log "Removing archive for '$archive_file' - Incorrect md5 checksum." __rvm_rm_rf "${rvm_archives_path}/$archive_file" fi fi done rvm_log "Archives repaired" return 0 } repair_all() { repair_symlinks repair_archives repair_environments repair_wrappers return 0 } args=($*) action="${args[$__array_start]}" args[$__array_start]="" args=(${args[@]}) if [[ -z "$action" ]] then usage exit $? fi case "$action" in all) repair_all symlinks) repair_symlinks gemsets) repair_gemsets environments) repair_environments archives) repair_archives wrappers) repair_wrappers help) usage *) usage >&2 ; exit 1 esac exit $? ;; ;; ;; ;; ;; ;; ;; ;; 1.18.28. initialize #!/usr/bin/env bash : rvm_trace_flag:${rvm_trace_flag:=0} if (( rvm_trace_flag > 0 )) then set -o xtrace # set -o errexit if [[ -z "${ZSH_VERSION:-}" ]] then # set -o errtrace # set -o pipefail export PS4 PS4="+ \${BASH_SOURCE##\${rvm_path:-}} : \${FUNCNAME[0]:+\${FUNCNAME[0]}()} \${LINENO} > " fi elif [[ ${rvm_debug_flag:-0} > 0 ]] then rvm_debug_flag=0 fi # Set shell options that RVM cannot live without, # see __rvm_setup and __rvm_teardown for further settings. if [[ -n "${BASH_VERSION:-}" ]] then shopt -s extglob elif [[ -n "${ZSH_VERSION:-}" ]] then setopt extendedglob setopt kshglob setopt no_glob_subst else printf "%b" "What the heck kind of shell are you running here???\n" fi export __rvm_env_loaded # set env loaded flag if not yet set : __rvm_env_loaded:${__rvm_env_loaded:=0}: # increase load count counter : __rvm_env_loaded:$(( __rvm_env_loaded+=1 )): # load only if not yet loaded or first time loading if [[ -z "${rvm_tmp_path:-}" ]] || (( __rvm_env_loaded == 1 )) then if typeset -f __rvm_cleanse_variables >/dev/null 2>&1 then __rvm_cleanse_variables fi # Ensure that /etc/rvmrc and $HOME/.rvmrc values take precedence. if (( ${rvm_ignore_rvmrc:=0} == 0 )) then rvm_stored_umask=$(umask) rvm_rvmrc_files=("/etc/rvmrc" "$HOME/.rvmrc") if [[ -n "${rvm_prefix:-}" ]] && ! [[ "$HOME/.rvmrc" -ef "${rvm_prefix}/.rvmrc" ]] then rvm_rvmrc_files+=( "${rvm_prefix}/.rvmrc" ) fi for rvmrc in "${rvm_rvmrc_files[@]}" do if [[ -f "$rvmrc" ]] then if GREP_OPTIONS="" \grep '^\s*rvm .*$' "$rvmrc" >/dev/null 2>&1 then printf "%b" " Error: $rvmrc is for rvm settings only. rvm CLI may NOT be called from within $rvmrc. Skipping the loading of $rvmrc" return 1 else source "$rvmrc" fi fi done unset rvm_rvmrc_files fi export rvm_path if [[ -z "${rvm_path:-}" ]] then if (( UID == 0 )) && [[ -d "/usr/local/rvm" ]] then rvm_path="/usr/local/rvm" elif [[ -d "${HOME}/.rvm" ]] then rvm_path="${HOME}/.rvm" elif [[ -d "/usr/local/rvm" ]] then rvm_path="/usr/local/rvm" else echo "Can't find rvm install!" 1>&2 ; exit 1 fi fi true ${rvm_scripts_path:="$rvm_path/scripts"} # # Setup RVM Environment variables. Each RVM internal path is intended to be # configurable by the end users for whatever their needs may be. # They should be set in /etc/rvmrc and then $HOME/.rvmrc # if [[ -z "${rvm_user_install_flag:-}" ]] then export rvm_user_install_flag rvm_man_path if (( UID == 0 )) || [[ -n "${rvm_prefix:-}" && "${rvm_prefix:-}" != "${HOME}" ]] then true "${rvm_man_path:="${rvm_prefix}/share/man"}" rvm_user_install_flag=0 else rvm_user_install_flag=1 fi fi : \ rvm_bin_path:${rvm_bin_path:="$rvm_path/bin"} \ rvm_man_path:${rvm_man_path:="$rvm_path/man"} \ rvm_archives_path:${rvm_archives_path:="$rvm_path/archives"} \ rvm_docs_path:${rvm_docs_path:="$rvm_path/docs"} \ rvm_environments_path:${rvm_environments_path:="$rvm_path/environments"} \ rvm_examples_path:${rvm_examples_path:="$rvm_path/examples"} \ rvm_gems_path:${rvm_gems_path:="$rvm_path/gems"} \ rvm_gemsets_path:${rvm_gemsets_path:="$rvm_path/gemsets"} \ rvm_help_path:${rvm_help_path:="$rvm_path/help"} \ rvm_hooks_path:${rvm_hooks_path:="$rvm_path/hooks"} \ rvm_lib_path:${rvm_lib_path:="$rvm_path/lib"} \ rvm_log_path:${rvm_log_path:="$rvm_path/log"} \ rvm_patches_path:${rvm_patches_path:="$rvm_path/patches"} \ rvm_repos_path:${rvm_repos_path:="$rvm_path/repos"} \ rvm_rubies_path:${rvm_rubies_path:="$rvm_path/rubies"} \ rvm_externals_path:${rvm_externals_path:="$rvm_path/externals"} \ rvm_rubygems_path:${rvm_rubygems_path:="$rvm_path/rubygems"} \ rvm_src_path:${rvm_src_path:="$rvm_path/src"} \ rvm_tmp_path:${rvm_tmp_path:="$rvm_path/tmp"} \ rvm_user_path:${rvm_user_path:="$rvm_path/user"} \ rvm_usr_path:${rvm_usr_path:="$rvm_path/usr"} \ rvm_wrappers_path:${rvm_wrappers_path:="$rvm_path/wrappers"} \ rvm_verbose_flag:${rvm_verbose_flag:=0} \ rvm_debug_flag:${rvm_debug_flag:=0} \ rvm_gems_cache_path:${rvm_gems_cache_path:=${rvm_gems_path:-"$rvm_path/gems"}/cache} export rvm_action rvm_alias_expanded rvm_archive_extension rvm_archives_path rvm_bin_flag rvm_bin_path rvm_configure_flags rvm_debug_flag rvm_default_flag rvm_delete_flag rvm_docs_path rvm_docs_type rvm_dump_environment_flag rvm_environments_path rvm_error_message rvm_examples_path rvm_expanding_aliases rvm_file_name rvm_gemdir_flag rvm_gems_cache_path rvm_gems_path rvm_gemset_name rvm_gemset_separator rvm_gemsets_path rvm_gemstone_package_file rvm_gemstone_url rvm_head_flag rvm_help_path rvm_hook rvm_hooks_path rvm_install_args rvm_install_on_use_flag rvm_lib_path rvm_llvm_flag rvm_loaded_flag rvm_log_path rvm_make_flags rvm_niceness rvm_nightly_flag rvm_only_path_flag rvm_parse_break rvm_patch_names rvm_patch_original_pwd rvm_patches_path rvm_path rvm_pretty_print_flag rvm_proxy rvm_quiet_flag rvm_ree_options rvm_reload_flag rvm_remove_flag rvm_repos_path rvm_rubies_path rvm_ruby_alias rvm_ruby_aliases rvm_ruby_args rvm_ruby_binary rvm_ruby_bits rvm_ruby_configure rvm_ruby_file rvm_ruby_gem_home rvm_ruby_gem_path rvm_ruby_global_gems_path rvm_ruby_home rvm_ruby_interpreter rvm_ruby_irbrc rvm_ruby_load_path rvm_ruby_major_version rvm_ruby_make rvm_ruby_make_install rvm_ruby_minor_version rvm_ruby_mode rvm_ruby_name rvm_ruby_package_file rvm_ruby_package_name rvm_ruby_patch rvm_ruby_patch_level rvm_ruby_release_version rvm_ruby_repo_url rvm_ruby_require rvm_ruby_revision rvm_ruby_selected_flag rvm_ruby_sha rvm_ruby_string rvm_ruby_strings rvm_ruby_tag rvm_ruby_url rvm_ruby_user_tag rvm_ruby_version rvm_script_name rvm_scripts_path rvm_sdk rvm_user_install_flag rvm_silent_flag rvm_src_path rvm_sticky_flag rvm_system_flag rvm_tmp_path rvm_token rvm_trace_flag rvm_use_flag rvm_user_flag rvm_user_path rvm_usr_path rvm_verbose_flag rvm_wrapper_name rvm_wrappers_path rvm_ruby_repo_branch rvm_man_path rvm_architectures fi # if [[ -z "${rvm_tmp_path:-}" ]] || (( __rvm_env_loaded == 1 )) 1.18.29. info #!/usr/bin/env bash if [[ "$rvm_trace_flag" -eq 2 ]] ; then set -x ; export rvm_trace_flag ; fi source "$rvm_scripts_path/base" source "$rvm_scripts_path/version" version_for() { typeset binary binary=${1:-""} if builtin command -v "$binary" >/dev/null ; then $binary --version | head -n1 else echo "not installed" fi return 0 } info_system() { rvm_info=" system: uname: bash: zsh: " } \"$(uname -a)\" \"$(command -v bash) => $(version_for bash)\" \"$(command -v zsh) => $(version_for zsh)\" print_part() { (( $1 )) || return typeset ret ret="$1 $2" (( $1 == 1 )) || ret="${ret}s" printf "$ret " } info_rvm() { typeset installed_at years months days hours minutes seconds part rvm_info=" rvm: version: \"$(__rvm_version | \tr "\n" ' ' | __rvm_strip)\" " rvm_info="${rvm_info} updated: \"" installed_at="$(cat ${rvm_path}/installed.at)" if [[ -n "${installed_at:-}" ]] && (( installed_at )) then seconds="$(( $(date +%s) - installed_at ))" if (( seconds )) then minutes="$(( seconds / 60 % 60 ))" hours="$(( seconds / 3600 % 24 ))" days="$(( seconds / 86400 % 31 ))" months="$(( seconds / 2678400 % 12 ))" years="$(( seconds / 31536000 ))" seconds="$(( seconds % 60 ))" for part in year month day hour minute second do eval "rvm_info=\"\${rvm_info}\$(print_part \${${part}s} ${part})\"" done rvm_info="${rvm_info}ago" else rvm_info="${rvm_info}just now" fi else rvm_info="${rvm_info}can not read installation time\n" fi rvm_info="${rvm_info}\"\n" } info_ruby() { [[ "$(__rvm_env_string)" == "system" ]] && return ruby=$(builtin command -v ruby) if [[ $? -eq 0 ]] && [[ -x "$ruby" ]] ; then full_version="$($ruby -v)" ; fi rvm_info=" ruby: interpreter: \"$(printf "%b" "${full_version}" | awk '{print $1}')\" version: \"$(printf "%b" "${full_version}" | awk '{print $2}')\" date: \"$(printf "%b" "${full_version}" | sed 's/^.*(\([0-9]\{4\}\(-[0-9][0-9]\)\{2\}\).*$/\1/')\" platform: \"$(printf "%b" "${full_version}" | sed 's/^.*\[//' | sed 's/\].*$//')\" patchlevel: \"$(printf "%b" "${full_version}" | sed 's/^.*(//' | sed 's/).*$//')\" full_version: \"${full_version}\" " } info_homes() { rvm_info=" homes: gem: ruby: " } info_binaries() { rvm_info=" binaries: ruby: irb: gem: rake: " } \"${GEM_HOME:-"not set"}\" \"${MY_RUBY_HOME:-"not set"}\" \"$(command \"$(command \"$(command \"$(command -v -v -v -v ruby)\" irb)\" gem)\" rake)\" info_environment() { rvm_info=" environment: PATH: \"${PATH:-""}\" GEM_HOME: \"${GEM_HOME:-""}\" GEM_PATH: \"${GEM_PATH:-""}\" MY_RUBY_HOME: \"${MY_RUBY_HOME:-""}\" IRBRC: \"${IRBRC:-""}\" RUBYOPT: \"${RUBYOPT:-""}\" gemset: \"$(__rvm_current_gemset)\"\n " if [[ -n "${MAGLEV_HOME:-""}" ]] ; then rvm_info="$rvm_info\n MAGLEV_HOME: \"$MAGLEV_HOME\"" fi rvm_info="$rvm_info\n" } info_debug() { rvm_info=" $(__rvm_version) $("$rvm_scripts_path/info" "$rvm_ruby_string" "" ) PATH:\n$(printf "%b" "$PATH" | awk -F":" '{print $1":"$2":"$3":"$4":"$5}' ) uname -a: $(uname -a) permissions: $(\ls -la "$rvm_path" "$rvm_rubies_path") " if [[ "Darwin" == "$(uname)" ]] ; then rvm_info="$rvm_info uname -r: $(uname -r) uname -m: $(uname -m) sw_vers: $(sw_vers | \tr "\n" ',') ARCHFLAGS: ${ARCHFLAGS:-""} LDFLAGS: ${LDFLAGS:-""} CFLAGS: ${CFLAGS:-""} /Developer/SDKs/*:$(/usr/bin/basename -a /Developer/SDKs/* | \tr "\n" ',') " fi for file_name in "$HOME/.bashrc" "$HOME/.bash_profile" "$HOME/.zshenv" ; do if [[ -s "$file_name" ]] ; then rvm_info="$rvm_info\n$file_name:\n$(GREP_OPTIONS="" \grep 'rvm' "$file_name" 2>/dev/null || true)" fi done if (( ${rvm_user_install_flag:=0} == 0 )) then debug_files=("$rvm_path/config/alias" "$rvm_path/config/system" "$rvm_path/config/db" "/etc/rvmrc" "/etc/gemrc") else debug_files=("$rvm_path/config/alias" "$rvm_path/config/system" "$rvm_path/config/db" "$HOME/.rvmrc" "$HOME/.gemrc") fi for file_name in "${debug_files[@]}" ; do if [[ -f "$file_name" && -s "$file_name" ]] ; then rvm_info="$rvm_info\n$file_name \(filtered\):\n$(awk '!/assword|_key/' "$file_name" )\n" fi done rvm_info="$rvm_info\ngem sources:\n$(gem sources | awk '/gems/')\n\n" } info_sections() { for section in $(printf "%b" "${sections//,/ }") ; do rvm_info="" "info_${section}" printf "%b" "$rvm_info" done } rvm_ruby_gem_home="${rvm_ruby_gem_home:-${GEM_HOME:-""}}" if [[ ! -d "$rvm_ruby_gem_home" ]] && builtin command -v gem > /dev/null 2>&1; then rvm_ruby_gem_home="$(gem env home)" fi rvm_info="" args=($*) ruby_strings="${args[$__array_start]// /}" args[$__array_start]="" args=(${args[@]}) sections="${args// /}" all_sections="system rvm ruby homes binaries environment" # TODO: Figure out what was the thought here and remove external match script # dependency if "$rvm_scripts_path/match" "$all_sections debug" "${ruby_strings/,*/}" ; then sections="$ruby_strings" ruby_strings="" fi if [[ -z "${sections// /}" ]] ; then sections="$all_sections" fi rvm_is_a_shell_function || true if [[ -z "$ruby_strings" ]] ; then printf "%b" "\n$(__rvm_env_string):\n" info_sections else for ruby_string in $(printf "%b" ${ruby_strings//,/ }) ; do __rvm_become "$ruby_string" printf "%b" "\n$(__rvm_env_string):\n" info_sections done fi exit 0 1.18.30. set #!/usr/bin/env bash source "$rvm_scripts_path/base" __rvm_attempt_single_exec() { # Return if we have multiple rubies. or we're not running exec. if (( ${#rvm_ruby_strings[@]} == 1 )) then __rvm_become "$rvm_ruby_strings" __rvm_load_rvmrc export rvm_project_rvmrc=0 rvm_ignore_rvmrc=1 exec "${args[@]}" fi return 1 } __rvm_ruby_do() { # Return on invalid rubies. __rvm_become "$current_set_ruby" || return 1 rvm_hook="before_do" source "$rvm_scripts_path/hook" if [[ -n "$rvm_json_flag" || -n "$rvm_yaml_flag" || -n "$rvm_summary_flag" ]] then if [[ ! -d "./log/$rvm_ruby_string/" ]] then mkdir -p "./log/$rvm_ruby_string/" fi touch "./log/$rvm_ruby_string/$action.log" "${args[@]}" >> "./log/$rvm_ruby_string/$action.log" 2>&1 else if (( ${rvm_verbose_flag:-0} > 0 )) then current_env="$(__rvm_env_string)" if [[ "$current_env" != "$current_set_ruby" ]] then current_env="$current_set_ruby ($current_env)" fi rvm_log "$current_env: $(ruby -v $rvm_ruby_mode | \tr "\n" ' ')\n" unset current_env fi ( __rvm_load_rvmrc export rvm_project_rvmrc=0 rvm_ignore_rvmrc=1 "${args[@]}" ) fi result=$? string=$rvm_ruby_string #$(basename $rvm_ruby_gem_home) if (( result == 0 )) then eval "successes=(${successes[*]} $string)" else eval "errors=(${errors[*]} $string)" fi eval "rubies=(${rubies[*]} $string)" eval "statuses=(${statuses[*]} $result)" unset string rvm_hook="after_do" source "$rvm_scripts_path/hook" __rvm_unset_ruby_variables } # Output the summary in a human readable format. __rvm_summary() { export successes errors statuses summary="\nSummary:\n\n" if [[ ${#successes[*]} -gt 0 ]] then if rvm_pretty_print stdout then summary="$summary ${rvm_notify_clr:-}${#successes[*]} successful: $(echo "${successes[*]}" | sed 's# #, #g')${rvm_reset_clr:-}\n" else summary="$summary ${#successes[*]} successful: $(echo "${successes[*]}" | sed 's# #, #g')\n" fi fi if [[ ${#errors[*]} -gt 0 ]] ; then if rvm_pretty_print stdout then summary="$summary ${rvm_error_clr:-}${#errors[*]} errors: $(echo "${errors[*]}" | sed 's# #, #g')${rvm_reset_clr:-}\n" else summary="$summary ${#errors[*]} errors: $(echo "${errors[*]}" | sed 's# #, #g')\n" fi fi total=${#rubies[*]} [[ -z "${ZSH_VERSION:-}" ]] ; array_start=$? printf "%b" "$summary" | tee -a log/summary.log return ${#errors[*]} } # Output the summary in a yaml format. __rvm_yaml() { export successes errors statuses yaml="totals:\n rubies: ${#rubies[*]}\n successes: ${#successes[*]}\n for var in ${successes[*]} ; do yaml="$yaml\n yaml="$yaml\nerrors:" for var in ${errors[*]} ; do yaml="$yaml\n yaml="$yaml\nrubies:" total=${#rubies[*]} errors: ${#errors[*]}\nsuccesses:" - $var" ; done - $var" ; done [[ -z "${ZSH_VERSION:-}" ]] ; array_start=$? for (( index = $array_start ; index < $total + $array_start ; index++ )) ; do if [[ ${rvm_debug_flag:-0} -gt 0 ]] ; then rvm_debug "${rubies[$index]}: ${statuses[$index]}" fi yaml="$yaml\n \"${rubies[$index]}\": ${statuses[$index]}" done unset index array_start \mkdir -p log printf "%b" "$yaml" | tee -a log/summary.yaml return ${#errors[*]} } # Output the summary in a json format. __rvm_json() { typeset index array_start json="{ \"totals\": { \"rubies\": ${#rubies[*]}, \"successes\": ${#successes[*]}, \"errors\": ${#errors[*]} }, \"successful\": [$(echo \"${successes[*]}\" | sed 's# #", "#g' | sed 's#\"\"##')], \"errors\": [$(echo \"${errors[*]}\" | sed 's# #", "#g' | sed 's#\"\"##')], \"rubies\": { " total=${#rubies[*]} [[ -z "${ZSH_VERSION:-}" ]] ; array_start=$? for (( index = $array_start ; index < $total + $array_start ; index++ )) ; do if [[ ${rvm_debug_flag:-0} -gt 0 ]] ; then rvm_debug "${rubies[$index]}: ${statuses[$index]}" fi json="$json\n {\"${rubies[$index]}\": ${statuses[$index]}}" if (( $index + 1 < $total + $array_start )) ; then json="$json, " ; fi done json="$json\n }\n}" if [[ ! -d log ]] ; then mkdir -p log fi printf "%b" "$json" | tee -a log/summary.json return ${#errors[*]} } # Loop over a set or all rvm installed rubies to perform some action. # Record the results and report based on CLI selections. rubies=() ; successes=() ; errors=() ; statuses=() args=( "$@" ) action="${args[$__array_start]}" unset args[$__array_start] args=( "${args[@]}" ) if [[ -z "$action" ]] then rvm_error "Action must be specified." exit 1 elif [[ "$action" != "do" ]] then rvm_error "Only 'do' action is allowed." exit 1 fi if [[ -z "${rvm_ruby_strings}" ]] then # TODO: deprecation issued on 2011.10.22, for RVM 1.9.0 rvm_warn "\`rvm do ${args[@]}\` is deprecated, use \`rvm all do ${args[@]}\` or \`rvm 1.9.2 do ${args[@]}\` instead." fi previous_rvm_ruby_strings="$rvm_ruby_strings" rvm_ruby_strings=( $( __rvm_expand_ruby_string "$rvm_ruby_strings" ) ) || { __rvm_ruby_strings_exist ${previous_rvm_ruby_strings} >/dev/null 2>/dev/null rvm_error "Ruby ${previous_rvm_ruby_strings} is not installed." exit 1 } unset previous_rvm_ruby_strings __rvm_attempt_single_exec for current_set_ruby in ${rvm_ruby_strings[@]} do __rvm_ruby_do done if [[ -n "$rvm_summary_flag" ]] ; then __rvm_summary ; fi if [[ -n "$rvm_yaml_flag" ]] ; then __rvm_yaml ; fi if [[ -n "$rvm_json_flag" ]] ; then __rvm_json ; fi rvm_hook="after_do" ; source "$rvm_scripts_path/hook" exit ${#errors[*]} 1.18.31. override_gem #!/usr/bin/env bash if [[ ${rvm_leave_gem_alone:-0} -eq 0 ]] then function gem { typeset result ( typeset rvmrc rvm_rvmrc_files=("/etc/rvmrc" "$HOME/.rvmrc") if [[ -n "${rvm_prefix:-}" ]] && ! [[ "$HOME/.rvmrc" -ef "${rvm_prefix}/.rvmrc" ]] then rvm_rvmrc_files+=( "${rvm_prefix}/.rvmrc" ) fi for rvmrc in "${rvm_rvmrc_files[@]}" do [[ -s "${rvmrc}" ]] && source "${rvmrc}" || true done unset rvm_rvmrc_files command gem "$@" ) || result=$? hash -r return ${result:-0} } fi 1.18.32. rubygems #!/usr/bin/env bash source "$rvm_scripts_path/base" source "$rvm_scripts_path/functions/db" result=0 __rvm_become rubygems_remove() { typeset rubygems_path ruby entry rvm_log "Removing old Rubygems files..." if [[ "$rvm_ruby_interpreter" == "rbx" ]] then ruby="puts Config::CONFIG['prefix']" elif [[ "$rvm_ruby_string" =~ ruby-1.9.3.* ]] then ruby="puts RbConfig::CONFIG.values_at('sitelibdir','vendorlibdir').detect { |path| File.directory?(File.join(path.to_s, 'rubygems')) }.to_s" else ruby="puts Config::CONFIG.values_at('sitelibdir','vendorlibdir').detect { |path| File.directory?(File.join(path.to_s, 'rubygems')) }.to_s" fi rubygems_path="$(ruby -rrbconfig -e "$ruby")" # Remove common files installed by ruby gems. entries=( "${rubygems_path}/ubygems.rb" "${rubygems_path}/gauntlet_rubygems.rb" "${rubygems_path}/rbconfig/" ) for entry in "${entries[@]}" "${rubygems_path}/rubygems"* do __rvm_rm_rf "$entry" done } can_switch_rubygems() { case "$rvm_ruby_string" in jruby*|maglev*) return 1 ;; *) return 0 ;; esac } rubygems_version_list() { curl -s https://api.github.com/repos/rubygems/rubygems/tags | sed -n '/"name": / {s/^.*".*": "v\(.*\)".*$/\1/; p;}' | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n } rubygems_master_sha() { curl -s "https://api.github.com/repos/rubygems/rubygems/commits?page=last&per_page=1" | sed -n '/^ "\(.*\)".*$/\1/;p;}' } rubygems_select_version_url() { case "$version" in latest|current) case "$rvm_ruby_string" in ruby-1.8*|ree-1.8*) typeset _rbv _rbv=${rvm_ruby_version##*.} if (( _rbv <= 5 )) then version=1.3.5 elif (( _rbv == 6 )) then version=1.3.7 fi ;; esac ;; esac case "$version" in latest|current) version="$(__rvm_db "${rvm_ruby_string//-/_}_rubygems_version")" version="${version:-"$(__rvm_db "${rvm_ruby_interpreter}_rubygems_version")"}" version="${version:-"$(__rvm_db "rubygems_version")"}" ;; "sha":/ {s/^.*".*": esac case "$version" in latest-*) version="${version#latest-}" version="$(rubygems_version_list | GREP_OPTIONS="" \grep "^${version}\." | tail -n 1 )" version="${version}" ;; esac case "${version}" in head|master) typeset sha sha="$(rubygems_master_sha)" rvm_rubygems_version="$version" rvm_gem_package_name="rubygems-rubygems-${sha:0:7}" rvm_gem_url="https://github.com/rubygems/rubygems/tarball/${sha}" ;; *) rvm_rubygems_version="$version" rvm_gem_package_name="rubygems-${rvm_rubygems_version}" rvm_rubygems_url=$(__rvm_db "rubygems_url") rvm_gem_url="${rvm_rubygems_url}/${rvm_gem_package_name}.tgz" ;; esac } rubygems_setup() { __rvm_warn_on_rubyopt true ${rvm_ruby_selected_flag:=0} unset RUBYOPT if (( rvm_ruby_selected_flag == 0 )) then __rvm_select fi rubygems_select_version_url # Sanity check... If setup.rb is missing from the rubygems source path, # something went wrong. Cleanup, aisle 3! if [[ ! -f "${rvm_src_path}/$rvm_gem_package_name/setup.rb" ]] then __rvm_rm_rf "${rvm_src_path}/$rvm_gem_package_name" fi if [[ ! -d "${rvm_src_path}/${rvm_gem_package_name}" ]] then rvm_log "Retrieving $rvm_gem_package_name" "$rvm_scripts_path/fetch" "$rvm_gem_url" "${rvm_gem_package_name}.tgz" result=$? if (( result > 0 )) then rvm_error "There has been an error while trying to fetch the source. \nHalting the installation." return $result fi if [[ ! -d "${rvm_src_path}/$rvm_gem_package_name" ]] then \mkdir -p "${rvm_src_path}/$rvm_gem_package_name" fi __rvm_run "rubygems.extract" \ "gunzip < ${rvm_archives_path}/$rvm_gem_package_name.tgz | $rvm_tar_command xf - -C ${rvm_src_path}" \ "Extracting $rvm_gem_package_name ..." fi rubygems_remove # Remove old gems. builtin cd "${rvm_src_path}/$rvm_gem_package_name" __rvm_run "rubygems.install" \ "GEM_PATH=\"$GEM_PATH:${GEM_PATH%%@*}@global\" GEM_HOME=\"$GEM_HOME\" \"${rvm_ruby_binary}\" \"${rvm_src_path}/$rvm_gem_package_name/setup.rb\"" \ "Installing $rvm_gem_package_name for ${rvm_ruby_string} ..." result=$? if (( result == 0 )) then typeset program_suffix program_suffix="$(${rvm_ruby_binary} -rrbconfig -e "puts RbConfig::CONFIG['configure_args']")" case "${program_suffix:-}" in (*--program-suffix=*) program_suffix="${program_suffix#*--program-suffix=}" program_suffix="${program_suffix%%[\' ]*}" __rvm_run "link.gem" "ln -s \"$rvm_ruby_home/bin/gem${program_suffix}\" \ \"$rvm_ruby_home/bin/gem\"" "$rvm_ruby_string - #linking gem${program_suffix} -> gem " ;; esac rvm_log "Installation of rubygems completed successfully." else rvm_warn "Installation of rubygems did not complete successfully." fi if [[ ! -z "$rvm_ruby_major_version" ]] then ruby_lib_gem_path="$rvm_ruby_home/lib/ruby/gems/${rvm_ruby_release_version}.${rvm_ruby_major_version}" else ruby_lib_gem_path="$rvm_ruby_home/lib/ruby/gems/$interpreter" fi # Add ruby's gem path to ruby's lib direcotry. \mkdir -p "$(dirname $ruby_lib_gem_path)" __rvm_rm_rf "$ruby_lib_gem_path" if [[ -d "$rvm_ruby_gem_home" ]] then ln -fs "$rvm_ruby_gem_home" "$ruby_lib_gem_path" fi unset ruby_lib_gem_path } if ! builtin command -v ruby > /dev/null then rvm_error "'ruby' was not found, cannot install rubygems unless ruby is present (Do you have an RVM ruby installed & selected?)" exit 1 fi # # rvm rubygems X # args=($*) export version version="${args[0]}" args="$(echo ${args[@]:1})" # Strip trailing / leading / extra spacing. if [[ -z "$version" ]] then rvm_error "Usage: rvm rubygems [x.y.z|latest-x.y|latest|remove]" exit 1 fi if can_switch_rubygems then case "$version" in remove) rubygems_remove ;; *) rubygems_setup ;; esac else rvm_error "Rubygems version may only be set for an RVM MRI based Ruby, please select one and rerun." result=1 fi exit $result 1.18.33. wrapper #!/usr/bin/env bash default_flag="$rvm_default_flag" # Prevent recursion unset rvm_default_flag rvm_wrapper_name prefix source "$rvm_scripts_path/base" source "$rvm_scripts_path/initialize" usage() { printf "%b" " Usage: rvm wrapper ruby_string [wrapper_prefix] [binary[ binary[ ...]]] Binaries ruby, gem, rake, irb, rdoc, ri, testrb Notes For more information, see 'rvm help wrapper' Example # Wrap the spec binary as 'rails3_spec' for 1.9.2@rails3 rvm wrapper 1.9.2@rails3 rails3 spec # To create a single binary you can do the following, user$ rvm use --create 1.8.7@ey ; gem install ey user$ rvm wrapper 1.8.7@ey --no-prefix ey # So that it is clear I am now in a different env, user$ rvm 1.9.2 user$ ruby -v ruby 1.9.2p180 (2011-02-18 revision 30909) [x86_64-darwin10.7.0] # And we have the desired result, user$ ey Usage: ey [--help] [--version] COMMAND [ARGS] ... " } wrap() { if [[ -n "${file_name:-""}" ]] then mkdir -p "$(dirname "$file_name")" rm -f "$file_name" if (( UID == 0 )) then # ... this stuff should not be in here... path="${rvm_path:-"/usr/local/rvm"}" else path="${rvm_path:-"$HOME/.rvm"}" fi printf "%b" "#!/usr/bin/env bash if [[ -s \"$path/environments/${environment_identifier}\" ]] then source \"$path/environments/${environment_identifier}\" exec $binary_name \"\$@\" else echo \"ERROR: Missing RVM environment file: '$path/environments/${environment_identifier}'\" >&2 exit 1 fi " > "$file_name" if [[ -f "$file_name" ]] then chmod +x "$file_name" fi return 0 else rvm_error "wrap() : file_name unkown variable for wrap()." return 1 fi } symlink_binary() { # Generate the default wrapper with the given binary name. # We first check if we can wrap the binary and if we were able to, # we then symlink it into place. if wrap_binary && [[ -f "$file_name" ]] then rm -f "$rvm_bin_path/${prefix}_${binary_name##*\/}" ln -fs "$file_name" "$rvm_bin_path/${prefix}_${binary_name##*\/}" fi } wrap_binary() { # We wrap when the given binary is in the path or override_check is set to one. if [[ "$override_check" == "1" ]] || builtin command -v $binary_name > /dev/null then wrap else rvm_error "Binary '$binary_name' not found." return 1 fi } # Empty ruby string: show usage and exit. if (( $# == 0 )) then usage exit 1 else ruby_string="$1" shift if (( $# > 0 )) then prefix="$1" shift fi fi if [[ -z "$ruby_string" ]] then usage exit 1 fi binaries=($@) override_check=0 # Default the list of binaries to those we use regularily. if [[ ${#binaries[@]} -eq 0 ]] then binaries=(ruby gem irb ri rdoc rake erb testrb) fi # Use the correct ruby. __rvm_become "$ruby_string" || { rvm_error "Could not load ruby $ruby_string." exit 3 } __rvm_ensure_has_environment_files environment_identifier="$(__rvm_env_string)" # For each binary, we want to generate the wrapper / symlink # it to the existing wrapper if needed. for binary_name in "${binaries[@]}" do file_name="$rvm_wrappers_path/${environment_identifier}/${binary_name##*\/}" if (( ${rvm_default_flag:-0} > 0 )) then prefix="default" fi if [[ ! -d "$rvm_bin_path" ]] then mkdir -p "$rvm_bin_path" fi if [[ -z "${prefix:-}" ]] then override_check=1 wrap_binary # Symlink it into place. if [[ -f "$file_name" ]] then if [[ "$binary_name" == "ruby" ]] then destination="$rvm_bin_path/$environment_identifier" else destination="$rvm_bin_path/${binary_name##*\/}-${environment_identifier}" fi rm -f "$destination" ln -sf "$file_name" "$destination" fi elif [[ "--no-prefix" == "$prefix" ]] then override_check=1 wrap_binary if [[ -f "$file_name" ]] then destination="$rvm_bin_path/${binary_name##*\/}" if [[ -s "$destination" ]] then rm -f "$destination" fi ln -sf "$file_name" "$destination" fi else symlink_binary fi done exit $? 1.18.34. fetch #!/usr/bin/env bash rvm_base_except="selector" source "$rvm_scripts_path/base" result=0 # handled by teardown __rvm_cleanup_download() { [[ -f "$archive" ]] && __rvm_rm_rf "$archive" } record_md5() { case "$(uname)" in Darwin|FreeBSD) archive_md5="$(/sbin/md5 -q "${archive}")" ;; OpenBSD) archive_md5="$(/bin/md5 -q "${archive}")" ;; Linux|*) archive_md5="$(md5sum "${archive}")" archive_md5="${archive_md5%% *}" ;; esac if [[ -w "$rvm_path/config/md5" ]] then "$rvm_scripts_path/db" "$rvm_path/config/md5" "$archive" "$archive_md5" else "$rvm_scripts_path/db" "$rvm_user_path/md5" "$archive" "$archive_md5" fi } builtin cd "$rvm_archives_path" # args=($*) # Reserved for future use if [[ -z "$1" ]] ; then rvm_error "BUG: $0 called without an argument :/" exit 1 fi url="$1"; download=1 ; package_name="$2" if ! builtin command -v curl > /dev/null ; then rvm_error "rvm requires curl. curl was not found in your active path." exit 1 elif [[ ! -z ${rvm_proxy} ]] ; then fetch_command="curl -x${rvm_proxy} -f -L --create-dirs -C - " # -s for silent else fetch_command="curl -f -L --create-dirs -C - " # -s for silent fi if [[ ! -z "$package_name" ]] ; then fetch_command="${fetch_command} -o ${package_name} " archive="$package_name" else fetch_command="${fetch_command} -O " archive=$(basename "$url") fi [[ ${rvm_debug_flag:-0} -gt 0 ]] && rvm_debug "Fetching $archive" # Check first if we have the correct archive archive_md5="$("$rvm_scripts_path/db" "$rvm_path/config/md5" "$archive" | head -n1)" if [[ -z "$archive_md5" ]] then archive_md5="$("$rvm_scripts_path/db" "$rvm_user_path/md5" "$archive" | head -n1)" fi if [[ -e "$archive" && ! -z "$archive_md5" ]] ; then [[ ${rvm_debug_flag:-0} -gt 0 ]] && \ rvm_debug "Found archive and its md5, testing correctness" if ! "$rvm_scripts_path"/md5 "$rvm_archives_path/${archive}" "$archive_md5" ; then [[ ${rvm_debug_flag:-0} -gt 0 ]] && \ rvm_debug "Archive md5 did not match, downloading" download=1 else [[ ${rvm_debug_flag:-0} -gt 0 ]] && \ rvm_debug "Archive md5 matched, not downloading" download=0 result=0 fi else [[ ${rvm_debug_flag:-0} -gt 0 ]] && \ rvm_debug "No archive or no MD5, downloading" download=1 fi # try to convert the http url to a ftp url ftp_url="$(echo "$url" | sed -e 's/http:/ftp:/')" if [[ $download -gt 0 ]] ; then rm -f $archive eval $fetch_command "$url" ; result=$? if [[ $result -gt 0 ]] ; then retry=0 try_ftp=0 if [[ $result -eq 78 ]] ; then rvm_error "The requested url does not exist: '$url'" try_ftp=1 elif [[ $result -eq 22 ]] ; then rvm_error "The requested url does not exist: '$url'" try_ftp=1 elif [[ $result -eq 18 ]] ; then rvm_error "Partial file. Only a part of the file was transferred. Removing partial and re-trying." rm -f "$archive" retry=1 elif [[ $result -eq 33 ]] ; then [[ ${rvm_debug_flag:-0} -gt 0 ]] && \ rvm_debug "Server does not support 'range' command, removing '$archive'" rm -f "$archive" retry=1 else rvm_error "There was an error, please check ${rvm_log_path}/$rvm_ruby_string/*.log. Next we'll try to fetch via http." try_ftp=1 fi if [[ $retry -eq 1 ]] ; then eval $fetch_command "$url" ; result=$? if [[ $result -gt 0 ]] ; then rvm_error "There was an error, please check ${rvm_log_path}/$rvm_ruby_string/*.log" else record_md5 fi fi if [[ $try_ftp -eq 1 ]] ; then rvm_log "Trying ftp:// URL instead." eval $fetch_command "$ftp_url" ; result=$? if [[ $result -gt 0 ]] ; then rvm_error "There was an error, please check ${rvm_log_path}/$rvm_ruby_string/*.log" else record_md5 fi fi else record_md5 fi fi exit $result 1.18.35. update #!/usr/bin/env bash export PS4 PATH PS4="+ \${BASH_SOURCE##\${rvm_path:-}} : \${FUNCNAME[0]:+\${FUNCNAME[0]}()} \${LINENO} > " set -o errtrace if [[ "$*" =~ --trace ]] || (( ${rvm_trace_flag:-0} > 0 )) then # Tracing, if asked for. set -o xtrace export rvm_trace_flag=1 fi #Handle Solaris Hosts if [[ "$(uname -s)" == "SunOS" ]] then PATH="/usr/gnu/bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH" else PATH="/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/sbin:$PATH" fi if [[ -n "${rvm_user_path_prefix:-}" ]] then PATH="${rvm_user_path_prefix}:$PATH" fi shopt -s extglob source "$PWD/scripts/functions/installer" # source "$PWD/scripts/rvm" # # RVM Installer # install_setup true ${DESTDIR:=} # Parse RVM Installer CLI arguments. while (( $# > 0 )) do token="$1" shift case "$token" in (--auto) rvm_auto_flag=1 ;; (--path) rvm_path="$1" shift ;; (--version) rvm_path="${PWD%%+(\/)}" __rvm_version unset rvm_path exit ;; (--debug) export rvm_debug_flag=1 set -o verbose ;; (--trace) set -o xtrace export rvm_trace_flag=1 echo "$@" env | GREP_OPTIONS="" \grep '^rvm_' export PS4="+ \${BASH_SOURCE##\${rvm_path:-}} : \${FUNCNAME[0]:+\${FUNCNAME[0]}()} ;; (--help) install_usage exit 0 ;; (*) echo "Unrecognized option: $token" install_usage exit 1 ;; esac done if [[ -n "${DESTDIR}" ]] then rvm_prefix="${DESTDIR}" fi determine_install_path determine_install_or_upgrade if [[ -z "${rvm_path:-}" ]] then echo "ERROR: rvm_path is empty, halting installation." \${LINENO} > " exit 1 fi export rvm_prefix rvm_path rvm_debug_flag rvm_trace_flag create_install_paths print_install_header configure_installation cleanse_old_entities install_rvm_files install_rvm_hooks ensure_scripts_are_executable setup_configuration_files install_binscripts automatic_profile_setup install_gemsets install_patchsets cleanse_old_environments migrate_old_gemsets migrate_defaults correct_binary_permissions install_man_pages root_canal setup_rvmrc setup_user_profile record_ruby_configs cleanup_tmp_files display_thank_you display_notes display_requirements 1.18.36. maglev #!/usr/bin/env bash source "$rvm_scripts_path/base" true ${rvm_trace_flag:-0} if (( rvm_trace_flag == 2 )) then set -x export rvm_trace_flag fi system="$(uname -s)" version="${rvm_ruby_string}.${system}" # Check we're on a suitable 64-bit machine case "$system" in Linux) if [[ "$(uname -sm)" != "Linux x86_64" ]] then rvm_error "This script only works on a 64-bit Linux OS." echo "The result from \"uname -sm\" is \"$(uname -sm)\" not \"Linux x86_64\"" exit 1 fi ;; Darwin) system_version="$(sw_vers -productVersion)" MAJOR="$(echo $system_version | cut -f1 -d.)" MINOR="$(echo $system_version | cut -f2 -d.)" CPU_CAPABLE="$(sysctl hw.cpu64bit_capable | cut -f2 -d' ')" # # Check the CPU and Mac OS profile. if [[ $CPU_CAPABLE -ne 1 || $MAJOR -lt 10 || $MINOR -lt 5 ]] then rvm_error "This script requires Mac OS 10.5 or later on a 64-bit Intel CPU." exit 1 fi ;; SunOS) if [[ "$(uname -p)" != "i386" || "$(isainfo -b)" != "64" ]] then rvm_error "This script only works on a 64-bit Solaris-x86 OS." exit 1 fi ;; *) rvm_error "This script only works on a 64-bit Linux, Mac OS X, or Solaris-x86 machine" echo "The result from \"uname -sm\" is \"$(uname -sm)\"" exit 1 ;; esac # We should run this as a normal user, not root. if (( UID == 0 )) then rvm_error "This script should be run as a normal user, not root." exit 1 fi # Check that the current directory is writable if [[ ! -w "." ]] then rvm_error "This script requires write permission on your current directory." \ls -ld $PWD exit 1 fi # We're good to go. Let user know. machine_name="$(uname -n)" rvm_log "Starting installation of $version on $machine_name" # Figure out how much total memory is installed rvm_log "Setting up shared memory" # # Ref: http://wiki.finkproject.org/index.php/Shared_Memory_Regions_on_Darwin # Ref: http://developer.postgresql.org/pgdocs/postgres/kernel-resources.html # Ref: http://www.idevelopment.info/data/Oracle/DBA_tips/Linux/LINUX_8.shtml # case "$system" in Linux) # use TotalMem: kB because Ubuntu doesn't have Mem: in Bytes totalMemKB=$(awk '/MemTotal:/{print($2);}' /proc/meminfo) totalMem=$(($totalMemKB * 1024)) # Figure out the max shared memory segment size currently allowed shmmax=$(cat /proc/sys/kernel/shmmax) # Figure out the max shared memory currently allowed shmall=$(cat /proc/sys/kernel/shmall) ;; Darwin) totalMem="$(sysctl hw.memsize | cut -f2 -d' ')" # Figure out the max shared memory segment size currently allowed shmmax="$(sysctl kern.sysv.shmmax | cut -f2 -d' ')" # Figure out the max shared memory currently allowed shmall="$(sysctl kern.sysv.shmall | cut -f2 -d' ')" ;; SunOS) # TODO: figure memory needs for SunOS # Investigate project.max-shm-memory totalMemMB="$(/usr/sbin/prtconf | GREP_OPTIONS="" \grep Memory | cut -f3 -d' ')" totalMem=$(($totalMemMB * 1048576)) shmmax=$(($totalMem / 4)) shmall=$(($shmmax / 4096)) ;; *) rvm_error "Can't determine operating system. Check script." exit 1 ;; esac totalMemMB=$(($totalMem / 1048576)) shmmaxMB=$(($shmmax / 1048576)) shmallMB=$(($shmall / 256)) # Print echo " echo " echo " current values Total memory available is $totalMemMB MB" Max shared memory segment size is $shmmaxMB MB" Max shared memory allowed is $shmallMB MB" # Figure out the max shared memory segment size (shmmax) we want # Use 75% of available memory but not more than 2GB shmmaxNew=$(($totalMem * 3/4)) if (( shmmaxNew > 2147483648 )) then shmmaxNew=2147483648 fi shmmaxNewMB=$(($shmmaxNew / 1048576)) # Figure out the max shared memory allowed (shmall) we want # The Darwin (OSX) default is 4MB, way too small # The Linux default is 2097152 or 8GB, so we should never need this # but things will certainly break if it's been reset too small # so ensure it's at least big enough to hold a fullsize shared memory segment shmallNew=$(($shmmaxNew / 4096)) if (( shmallNew < shmall )) then shmallNew=$shmall fi shmallNewMB=$(($shmallNew / 256)) # Increase shmmax if appropriate if (( shmmaxNew > shmmax )) then rvm_log "Increasing max shared memory segment size to $shmmaxNewMB MB" case "${system}" in Darwin) sudo sysctl -w kern.sysv.shmmax=$shmmaxNew ;; Linux) sudo bash -c "echo $shmmaxNew > /proc/sys/kernel/shmmax" ;; SunOS) echo "[[Warning]] shmmax must be set manually on SunOS" ;; esac else rvm_log "No need to increase max shared memory segment size" fi # Increase shmall if appropriate if (( shmallNew > shmall )) then rvm_log "Increasing max shared memory allowed to $shmallNewMB MB" case "${system}" in Darwin) sudo sysctl -w kern.sysv.shmall=$shmallNew ;; Linux) sudo bash -c "echo $shmallNew > /proc/sys/kernel/shmall" ;; SunOS) echo "[[Warning]]shmall must be set manually on SunOS" ;; esac else rvm_log "No need to increase max shared memory allowed" fi # At this point, shared memory settings contain the values we want, # put them in sysctl.conf so they are preserved. if [[ ! -f /etc/sysctl.conf ]] || (( $(GREP_OPTIONS="" \grep -sc "kern.*.shm" /etc/sysctl.conf) == 0 )) then case "$system" in Linux) echo "# kernel.shm* settings added by MagLev installation" > /tmp/sysctl.conf.$$ echo "kernel.shmmax=$(cat /proc/sys/kernel/shmmax)" >> /tmp/sysctl.conf.$$ echo "kernel.shmall=$(cat /proc/sys/kernel/shmall)" >> /tmp/sysctl.conf.$$ ;; Darwin) # On Mac OS X Leopard, you must have all five settings in sysctl.conf # before they will take effect. echo "# kern.sysv.shm* settings added by MagLev installation" > /tmp/sysctl.conf.$$ sysctl kern.sysv.shmmax kern.sysv.shmall kern.sysv.shmmin kern.sysv.shmmni \ kern.sysv.shmseg | \tr ":" "=" | \tr -d " " >> /tmp/sysctl.conf.$$ ;; SunOS) # Do nothing in SunOS since /etc/sysctl.conf is ignored on Solaris 10. # Must configure shared memory settings manually. ;; *) rvm_error "Can't determine operating system. Check script." exit 1 ;; esac # Do nothing on SunOS since /etc/sysctl.conf is ignored on Solaris 10. if [[ "$system" != "SunOS" ]] then rvm_log "Adding the following section to /etc/sysctl.conf" cat /tmp/sysctl.conf.$$ sudo bash -c "cat /tmp/sysctl.conf.$$ >> /etc/sysctl.conf" /bin/rm -f /tmp/sysctl.conf.$$ fi else rvm_log "The following shared memory settings already exist in /etc/sysctl.conf" echo "To change them, remove the following lines from /etc/sysctl.conf and rerun this script" GREP_OPTIONS="" \grep "kern.*.shm" /etc/sysctl.conf fi # Now setup for NetLDI in case we ever need it. rvm_log "Setting up GemStone netldi service port" if (( $(GREP_OPTIONS="" \grep -sc "^gs64ldi" /etc/services) == 0 )) then echo '[[Info]] Adding "gs64ldi 50378/tcp" to /etc/services' sudo bash -c 'echo "gs64ldi 50378/tcp # Gemstone netldi" >> /etc/services' else rvm_log "GemStone netldi service port is already set in /etc/services" echo "To change it, remove the following line from /etc/services and rerun this script" GREP_OPTIONS="" \grep "^gs64ldi" /etc/services fi 1.18.37. disk-usage #!/usr/bin/env bash rvm_base_except="selector" source "$rvm_scripts_path/base" usage() { printf "%b" \ "Usage: 'rvm disk-usage {all,total,archives,repos,sources,logs,pkg,rubies,gemsets,wrappers,tmp,others}' Lists the space rvm uses for a given item(s). " exit 1 } disk_usage() { typeset path name name="$1" path="$2" shift 2 printf "%${length}s" "${name} Usage: " if [[ -n "$path" && -d "$path" && "$path" != "/" ]] then du -hs "$@" "${path}/" | awk '{print $1}' else echo "0B" fi return 0 } all_disk_usage() { typeset name export length=30 for name in archives repos sources logs pkg \ rubies gemsets wrappers temporary others total do ${name}_disk_usage done } archives_disk_usage() repos_disk_usage() sources_disk_usage() logs_disk_usage() pkg_disk_usage() rubies_disk_usage() gemsets_disk_usage() wrappers_disk_usage() temporary_disk_usage() total_disk_usage() others_disk_usage() { typeset flag filter typeset -a flags { { { { { { { { { { disk_usage disk_usage disk_usage disk_usage disk_usage disk_usage disk_usage disk_usage disk_usage disk_usage "Downloaded Archives" "Repositories" "Extracted Source Code" "Log Files" "Packages" "Rubies" "Gemsets" "Wrappers" "Temporary Files" "Total Disk" "archives"; "repos"; "src"; "log"; "usr"; "rubies"; "gems"; "wrappers"; "tmp"; "."; } } } } } } } } } } if du --exclude=* . 2>/dev/null 1>/dev/null then flag="--exclude=" else flag="-I " fi for filter in archives repos src log usr rubies gems wrappers tmp do flags+=( ${flag}${filter} ) done disk_usage "Other Files" "." "${flags[@]}" } case "${1:-help}" in all|total|archives|repos|sources|logs|pkg|rubies|gemsets|wrappers|tmp|others) ( export length="" cd $rvm_path $1_disk_usage ) ;; help|*) usage ;; esac 1.18.38. tools #!/usr/bin/env bash source "$rvm_scripts_path/base" usage() { echo "Usage: rvm tools {identifier,path-identifier,strings,user}" 1>&2 exit 1 } # Return the identifier that's current in use. tools_identifier() { __rvm_env_string } tools_path_identifier() { if [[ -z "$1" || ! -d "$1" ]]; then echo "Usage: rvm tools path-identifier 'path-to-check'" return 1 fi builtin cd "$1" __rvm_do_with_env_before rvm_promptless=1 __rvm_project_rvmrc >/dev/null 2>&1 rvmrc_result="$?" __rvm_env_string __rvm_do_with_env_after exit $rvmrc_result } tools_strings() { for ruby_name in "$@"; do __rvm_unset_ruby_variables rvm_ruby_string="$ruby_name" if { __rvm_ruby_string && __rvm_select; } >/dev/null 2>&1; then basename "$rvm_ruby_gem_home" else echo "" fi done } tools_user_usage() { typeset msg for msg in "$@" do rvm_error "$msg" done rvm_error "Usage: rvm user [gemsets] [rubies] [hooks] [pkgs] [wrappers] [all] [--skel]" } tools_user_setup() { typeset target eval_target name path target="$1" name="rvm_${2}_path" # detect name in config if [[ -f "${target}/.rvmrc" ]] && GREP_OPTIONS="" \grep "^export ${name}=" "${target}/.rvmrc" > /dev/null then # if defined read path path="$( GREP_OPTIONS="" \grep "^export ${name}=" "${target}/.rvmrc" | sed "s/^export ${name}=//" )" else # if not defined - define it path="\${HOME}/.rvm/${2}" echo "export ${name}=\"${path}\"" >> "${target}/.rvmrc" fi # subprocess cause we change the HOME ( # set home to target, so --skel works fine HOME="${target}" # resolve the stored path eval "path=\"${path}\"" # ensure the defined path exists [[ -d "${path}" ]] || mkdir -p "${path}" # create empty db files for rvm_user_path if [[ "$1" == "user" ]] then for file in db md5 do [[ -f "${path}/${file}" ]] || touch "${path}/${file}" done fi ) } tools_user() { typeset item dir target typeset -a selection for item in $@ do case "$item" in all) selection+=( gemsets rubies hooks pkgs wrappers userdb ) ;; rubies) selection+=( rubies ) ;; gemsets) selection+=( gemsets ) ;; hooks) selection+=( hooks ) ;; pkgs) selection+=( pkgs ) ;; userdb) selection+=( userdb ) ;; --skel) rvm_skel_flag=1 ;; *) tools_user_usage "Unrecognized option '$item'." exit 1 ;; esac done if (( ${#selection[@]} == 0 )) then tools_user_usage exit 1 fi if [[ ${rvm_skel_flag:-0} == 1 ]] && (( UID )) then tools_user_usage "The --skel flag should be run as root: rvmsudo rvm user $@." exit 1 fi [[ ${rvm_skel_flag:-0} == 1 ]] && target=/etc/skel || target="${HOME}" if [[ ! -w "${target}" ]] || [[ -d "${target}/.rvm" && ! -w "${target}/.rvm" ]] then tools_user_usage "Directory '${target}' or '${target}/.rvm' is not writable for current user." exit 1 fi if [[ -f "${target}/.rvmrc" && ! -w "${target}/.rvmrc" ]] then tools_user_usage "Configuration file '${target}/.rvmrc' is not writable for current user." exit 1 fi for item in "${selection[@]}" do case "$item" in rubies) for dir in archives bin environments gems gems_cache log repos rubies rubygems src tmp wrappers user do tools_user_setup "${target}" $dir done ;; gemsets) for dir in environments gems gems_cache wrappers do tools_user_setup "${target}" $dir done ;; hooks) tools_user_setup "${target}" hooks ;; pkgs) tools_user_setup "${target}" usr ;; userdb) tools_user_setup "${target}" user ;; esac done } tools_mirror() { typeset n file warn warn=0 file="$rvm_user_path/db" for n in 1.0 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 do if GREP_OPTIONS="" \grep "^ruby_${n}_url=" "$file" >/dev/null then if (( ${rvm_force_flag:-0} == 1 )) then sed -i "s/^ruby_${n}_url=.*$/ruby_${n}_url=http:\/\/www.mirrorservice.org\/sites\/ftp.rubylang.org\/pub\/ruby\/${n}/" "$file" else warn=1 fi else printf "ruby_${n}_url=http://www.mirrorservice.org/sites/ftp.ruby-lang.org/pub/ruby/${n} " >> "$file" fi done if (( warn == 1 )) then rvm_warn "Some settings already exist, use 'rvm --force tools mirror' to overwrite." fi } tools_rvm_env() { typeset script rvm_log "# use shebang: #!/usr/bin/$1-rvm-env 1.9.3" for script in $@ do if builtin command -v ${script} >/dev/null then sudo ln -nfs $rvm_bin_path/rvm-shell /usr/bin/${script}-rvm-env && rvm_log "Created link '/usr/bin/${script}-rvm-env'." || rvm_error "Cannot create link '/usr/bin/${script}-rvm-env'." else rvm_error "There is no command/script '${script}' in system." fi done } args=($*) action="${args[0]}" args="$(echo ${args[@]:1})" # Strip trailing / leading / extra spacing. [[ -z "$action" ]] && usage case "$action" in identifier) path-identifier) strings) mirror) user) rvm-env) *) esac exit $? tools_identifier ;; tools_path_identifier "$args" ;; tools_strings "$args" ;; tools_mirror ;; tools_user "$args" ;; tools_rvm_env $args ;; usage ;; 1.18.39. irbrc # # # # # This loads some niceties for irb, courtesy of rvm. It also loads your custom ~/.irbrc if it exists. If you want to customize the irbrc for ONLY this version of ruby then edit this file. It will only be deleted if you do an "rvm install" over this ruby version. if ENV["rvm_path"].nil? require File.join(ENV["HOME"], "irbrc") else require File.join(ENV["rvm_path"], "scripts", "irbrc") end 1.18.40. alias #!/usr/bin/env bash unset rvm_default_flag rvm_wrapper_name source "$rvm_scripts_path/base" usage() { printf "%b" " Usage: rvm alias [action] [arguments] Examples: rvm rvm rvm rvm alias alias alias alias create [alias_name] [ruby] delete [alias_name] show [alias_name] list " } alias_conflicts_with_ruby() { # If default exists, we should return true. [[ "$1" == "default" && ! -L "$rvm_rubies_path/default" ]] && return 1 # Open for suggestions to a better way of doing this... alias_check_result="$( \. "$rvm_scripts_path/initialize" \. "$rvm_scripts_path/selector" \. "$rvm_scripts_path/selector_gemsets" export rvm_ruby_string=\"$1\" __rvm_ruby_string > /dev/null 2>&1 echo "$?" )" if [[ "0" == "$alias_check_result" ]]; then rvm_error "You have attempted to create an alias called '$1', which is recognized as a rvm ruby." return 0 fi return 1 unset alias_check_result } alias_show() { typeset expanded_alias_name if [[ -z "$alias_name" ]] then rvm_log "usage: 'rvm alias show [alias_name]'" result=1 return fi [[ -s "$rvm_path/config/alias" ]] || return 0 expanded_alias_name="$("$rvm_scripts_path"/db "$rvm_path/config/alias" "$alias_name")" if [[ -z "$expanded_alias_name" ]]; then rvm_error "Unknown alias name: '$alias_name'" result=1 else result=0 if [[ -n "$gemset_name" ]] ; then printf "%b" "${expanded_alias_name}${rvm_gemset_separator:-"@"}${gemset_name}\n" else printf "%b" "${expanded_alias_name}\n" fi fi } alias_after_delete_default() { rvm_log "Deleting default links/files" for _path in $rvm_bin_path/default_* "$rvm_environments_path/default" "$rvm_wrappers_path/default" do [[ -f "$_path" ]] && rm -rf ${_path} done for wrapper in "$rvm_path"/wrappers/default/* do wrapper="${wrapper##*\/}" if [[ -L "$rvm_bin_path/${wrapper}" ]] then rm -f "$rvm_bin_path/${wrapper}" fi rm -f "$rvm_bin_path/${wrapper}" # If the RVM bin path is different from rvm_path/bin, ensure they are # in sync. if [[ "${rvm_bin_path}" != "${rvm_path}/bin" ]] then rm -f "${rvm_path}/bin/${wrapper}" fi done } alias_delete() { rvm_log "Deleting alias: $alias_name" for link in "$rvm_rubies_path/$alias_name" ; do if [[ -L "$link" ]] ; then rm -f $link ; fi done [[ -s "$rvm_path/config/alias" ]] || return 0 "$rvm_scripts_path"/db "$rvm_path/config/alias" "$alias_name" "delete" if [[ "default" == "$alias_name" ]] ; then alias_after_delete_default fi } alias_after_create_default() { rvm_log "Creating default links/files" environment_id="${final_environment_identifier}" if (( ${rvm_user_install_flag:=0} == 0 )) then # Sets up the default wrappers. "$rvm_scripts_path/wrapper" "$rvm_ruby_string" --no-prefix else "$rvm_scripts_path/wrapper" "$rvm_ruby_string" "default" fi RUBY_VERSION="$("$rvm_ruby_home/bin/ruby" -v | \sed 's#^\(.*\) (.*$#\1#')" export GEM_HOME GEM_PATH MY_RUBY_HOME RUBY_VERSION for _path in "$rvm_environments_path" "$rvm_wrappers_path" do # Remove old default if it exists. [[ -L "$_path/default" ]] && rm -f "$_path/default" # Symlink n the new default \ln -fs "$_path/$environment_id" "$_path/default" done # Copy wrapper scripts for the newly set default to the RVM bin path. for wrapper in "$rvm_path"/wrappers/default/* do [[ -r "${wrapper}" ]] || continue if [[ -L "$rvm_bin_path/${wrapper##*\/}" ]] then rm -f "$rvm_bin_path/${wrapper##*\/}" fi cp -f "$wrapper" "$rvm_bin_path/${wrapper##*\/}" # If the RVM bin path is different from rvm_path/bin, ensure they are # in sync. if [[ "${rvm_bin_path}" != "${rvm_path}/bin" ]] then cp -f "${wrapper}" "${rvm_path}/bin/" fi done } alias_create() { alias_name="${alias_name:-""}" rvm_ruby_string="$rvm_environment_identifier" rvm_expanding_aliases=1 __rvm_become unset rvm_expanding_aliases if [[ "default" != "$alias_name" ]] && alias_conflicts_with_ruby "$alias_name" then # Force it to an empty alias name to trigger the usage. alias_name="" fi if [[ -z "${rvm_environment_identifier:-""}" || -z "$alias_name" ]] then rvm_error "usage: 'rvm alias [alias_name] [ruby_string]'" return 1 else if [[ -z "$rvm_ruby_string" ]] then rvm_error "Unknown ruby string '$rvm_ruby_string' specified" return 1 fi if [[ "default" == "$alias_name" ]] then rvm_alias="" fi if [[ -z "$rvm_alias" ]] then final_environment_identifier="${rvm_ruby_string:-$(__rvm_env_string)}" rvm_log "Creating alias $alias_name for $final_environment_identifier." ln -fs "$rvm_rubies_path/$rvm_ruby_string" "$rvm_rubies_path/$alias_name" rvm_log "Recording alias $alias_name for $final_environment_identifier." "$rvm_scripts_path"/db "$rvm_path/config/alias" "$alias_name" "$final_environment_identifier" [[ "default" != "$alias_name" ]] || alias_after_create_default else if [[ -d "$rvm_rubies_path/$alias_name" ]] then rvm_error "$rvm_rubies_path/$alias_name is taken and is *not* able to be an alias name." else rvm_error "$rvm_rubies_path/$alias_name is already aliased." fi return 1 fi fi } alias_list() { typeset item items items=($(cd "$rvm_rubies_path" ; find . -maxdepth 1 -mindepth 1 -type l | sed -e 's#./##')) for item in "${items[@]}" do echo "$(basename "$item") => $("$rvm_scripts_path"/db "$rvm_path/config/alias" "$(basename "$item")")" done } alias_search_by_target() { typeset item items target search search="${alias_name}@${gemset_name}" items=($(cd "$rvm_rubies_path" ; find . -maxdepth 1 -mindepth 1 -type l | sed -e 's#./##')) for item in "${items[@]}" do target=$("$rvm_scripts_path"/db "$rvm_path/config/alias" "$(basename "$item")") if [[ "${search}" == "${target}" ]] then echo "$(basename "$item")" fi done } args=($*) action="${args[0]:-""}" alias_name="${args[1]:-""}" rvm_environment_identifier="${args[2]:-""}" args="$(echo ${args[@]:3})" # Strip trailing / leading / extra spacing. result=0 if [[ ! -f "$rvm_path/config/alias" ]] ; then touch "$rvm_path/config/alias" ; fi if printf "%b" "$alias_name" | GREP_OPTIONS="" \grep "${rvm_gemset_separator:-"@"}" >/dev/null 2>&1 ; then gemset_name="${alias_name/*${rvm_gemset_separator:-"@"}/}" alias_name="${alias_name/${rvm_gemset_separator:-"@"}*/}" else gemset_name="" fi if [[ -n "$alias_name" ]] ; then rvm_alias="$("$rvm_scripts_path/db" "$rvm_path/config/alias" "$alias_name")" fi case "$action" in delete|create|list|show|search_by_target) alias_${action} ;; help|usage) usage ;; *) usage exit 1 ;; esac exit $? 1.18.41. irbrc.rb # This is the common irbrc file used by all rvm ruby installations. # This file will be overriden every time you update rvm. # Turn on completion. begin require "readline" require "irb/completion" rescue nil # Turn on history saving. # require "irb/ext/save-history" # IRB.conf[:HISTORY_FILE] = File.join(ENV["HOME"], ".irb-history") # Use an alternate way to on history saving until save-history is fixed. # # bug: http://redmine.ruby-lang.org/issues/show/1556 # patch: http://pastie.org/513500 # # This technique was adopted from /etc/irbrc on OS X. histfile = File.expand_path(".irb-history", ENV["HOME"]) if File.exists?(histfile) lines = IO.readlines(histfile).collect { |line| line.chomp } Readline::HISTORY.push(*lines) end Kernel::at_exit do maxhistsize = 100 histfile = File::expand_path(".irb-history", ENV["HOME"]) lines = Readline::HISTORY.to_a.reverse.uniq.reverse lines = lines[-maxhistsize, maxhistsize] if lines.compact.length > maxhistsize File::open(histfile, "w+") { |io| io.puts lines.join("\n") } end rescue LoadError puts "Readline was unable to be required, if you need completion or history install readline then reinstall the ruby.\nYou may follow 'rvm notes' for dependencies and/or read the docs page https://rvm.io/packages/readline/ . Be sure you 'rvm remove X ; rvm install X' to re-compile your ruby with readline support after obtaining the readline libraries." end # Calculate the ruby string. rvm_ruby_string = ENV["rvm_ruby_string"] || ENV['GEM_HOME'].nil? ? `ruby -v | awk '{printf $1"-"$2}'` : ENV['GEM_HOME'].split(/\//).last.split(/@/).first # cut ruby- ... everyone knows it's ruby rvm_ruby_string = $1 if rvm_ruby_string =~ /^ruby-(.*)/ # Set up the prompt to be RVM specific. @prompt = { :PROMPT_I => "#{rvm_ruby_string} :%03n > ", # default prompt :PROMPT_S => "#{rvm_ruby_string} :%03n%l> ", # known continuation :PROMPT_C => "#{rvm_ruby_string} :%03n > ", :PROMPT_N => "#{rvm_ruby_string} :%03n?> ", # unknown continuation :RETURN => " => %s \n", :AUTO_INDENT => true } IRB.conf[:PROMPT] ||= {} IRB.conf[:PROMPT][:RVM] = @prompt IRB.conf[:PROMPT_MODE] = :RVM if IRB.conf[:PROMPT_MODE] == :DEFAULT # Load the user's irbrc file, if possible. # Report any errors that occur. begin load File.join(ENV["HOME"], ".irbrc") if File.exists?("#{ENV["HOME"]}/.irbrc") rescue LoadError => load_error puts load_error rescue => exception puts "Error : 'load #{ENV["HOME"]}/.irbrc' : #{exception.message}" end 1.18.42. upgrade #!/usr/bin/env bash unset GREP_OPTIONS source "$rvm_scripts_path/base" usage() { printf "%b" " Usage: rvm upgrade [source ruby] [destination ruby] Description: Upgrades the specified (already installed) source ruby given to the given destination ruby version. Will migrate gemsets, wrappers, aliases and environment files. To upgrade rvm itself you want 'rvm get'. Examples: $ rvm upgrade 1.9.2-p136 1.9.2-p180 $ rvm upgrade ree-2011.01 ree-2011-02 " } confirm() { typeset confirmation_response printf "%b" "$1 (Y/n): " read -r confirmation_response if [[ -n "$confirmation_response" ]] then echo $confirmation_response | GREP_OPTIONS="" \grep -i '^y\|^Y' >/dev/null 2>&1 fi } die_with_error() { rvm_error "$1" exit "${2:-1}" } expand_ruby_name() { "$rvm_scripts_path/tools" strings "$1" \ | awk -F"${rvm_gemset_separator:-"@"}" '{print $1}' } existing_ruby_patch() { if "$rvm_scripts_path/list" strings | GREP_OPTIONS="" \grep "^$1$" >/dev/null then echo "$1" else ( rvm_ruby_string="$1" __rvm_ruby_string if "$rvm_scripts_path/list" strings | GREP_OPTIONS="" \grep "^${rvm_ruby_interpreter}-${rvm_ruby_version}-" >/dev/null then "$rvm_scripts_path/list" strings | GREP_OPTIONS="" \grep "^${rvm_ruby_interpreter}-${rvm_ruby_version}-" | sort | tail -n 1 else "$rvm_scripts_path/list" strings | GREP_OPTIONS="" \grep "^${rvm_ruby_interpreter}-" | sort | tail -n 1 fi ) fi } highest_ruby_patch() { typeset patch_level _version ( rvm_ruby_string=$1 __rvm_ruby_string patch_level="$( __rvm_db "${rvm_ruby_interpreter}_${rvm_ruby_version}_patch_level" )" _version="$( __rvm_db "${rvm_ruby_interpreter}_version" )" if [[ -n "${patch_level:-""}" ]] then case "$rvm_ruby_interpreter" in ree|kiji|rbx) # REE, Kiji & Rubinius use dates for their patch levels. rvm_ruby_patch_level="${patch_level}" ;; *) # MRI uses -pN+ to specify the patch level. rvm_ruby_patch_level="p${patch_level}" ;; esac echo ${rvm_ruby_interpreter}-${rvm_ruby_version}-${rvm_ruby_patch_level} elif [[ -n "${_version:-""}" ]] then echo ${rvm_ruby_interpreter}-${_version} else echo ${rvm_ruby_interpreter} fi ) } upgrade_ruby() { [[ -n "$expanded_source" ]] || die_with_error "The source ruby was not a valid ruby string." [[ -n "$expanded_destination" ]] || die_with_error "The destination ruby was not a valid ruby string." if ! confirm \ "Are you sure you wish to upgrade from $expanded_source to $expanded_destination?" then die_with_error "Cancelling upgrade." fi if [[ ! -d "$rvm_rubies_path/$expanded_destination" ]] then rvm_log "Installing new ruby $expanded_destination" if "${rvm_bin_path}/rvm" install "$expanded_destination" then true else die_with_error "Unable to install ruby $expanded_destination. Please install it manually to continue." $? fi fi rvm_log "Migrating gems from $expanded_source to $expanded_destination" "$rvm_scripts_path/migrate" "$expanded_source" "$expanded_destination" || die_with_error "Error migrating gems." "$result" rvm_log "Upgrade complete!" } args=($*) source_ruby="${args[$__array_start]:-}" args[$__array_start]="" args=(${args[@]}) destination_ruby="${args[$__array_start]:-}" args[$__array_start]="" args=(${args[@]}) expanded_source="$(existing_ruby_patch "$source_ruby")" if [[ -n "$source_ruby" && -z "$destination_ruby" ]] then highest_source="$(highest_ruby_patch "$(expand_ruby_name "$source_ruby")")" if [[ "${expanded_source}" != "${highest_source}" ]] then destination_ruby="$(expand_ruby_name "$highest_source")" fi fi if [[ -z "$source_ruby" || -z "$destination_ruby" ]] then usage >&2 exit 1 elif [[ "help" == "$source_ruby" ]] then usage else expanded_destination="$(expand_ruby_name "$destination_ruby")" upgrade_ruby fi 1.18.43. requirements #!/usr/bin/env bash ( # wrap color reseting if ! typeset -f rvm_pretty_print >/dev/null 2>&1 then source "${rvm_scripts_path:-"$rvm_path/scripts"}/functions/logging" fi rvm_pretty_print stdout || unset rvm_error_clr rvm_warn_clr rvm_debug_clr rvm_notify_clr rvm_reset_clr system="$(uname)" if [[ "Linux" == "$system" ]] || [[ "$(uname|tr a-z A-Z)" =~ *BSD* ]] then for file in /etc/*-release do release="( $(cat $file) )" break done printf "%b" " Requirements for ${system} $release " rvm_apt_binary="$(builtin command -v apt-get)" rvm_emerge_binary="$(builtin command -v emerge)" rvm_pacman_binary="$(builtin command -v pacman)" rvm_yum_binary="$(builtin command -v yum)" rvm_zypper_binary="$(builtin command -v zypper)" rvm_free_ram_mb="$(free -m | awk '{if (NR==3) print $4}')" printf "%b" " NOTE: 'ruby' represents Matz's Ruby Interpreter (MRI) (1.8.X, 1.9.X) This is the *original* / standard Ruby Language Interpreter 'ree' represents Ruby Enterprise Edition 'rbx' represents Rubinius bash >= 4.1 required curl is required git is required (>= 1.7 for ruby-head) patch is required (for 1.8 rubies and some ruby-head's). To install rbx and/or Ruby 1.9 head (MRI) (eg. 1.9.2-head), then you must install and use rvm 1.8.7 first. " if [[ ! -z "$rvm_apt_binary" ]] then printf "%b" " Additional Dependencies: # For Ruby / Ruby HEAD (MRI, Rubinius, & REE), install the following: ruby: ${rvm_apt_binary} install build-essential openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev automake libtool bison subversion # For JRuby, install the following: jruby: ${rvm_apt_binary} install curl g++ openjdk-6-jre-headless jruby-head: ${rvm_apt_binary} install ant openjdk-6-jdk # For IronRuby, install the following: ironruby: ${rvm_apt_binary} install curl mono-2.0-devel " elif [[ ! -z "$rvm_emerge_binary" ]] then printf "%b" " Additional Dependencies: # For Ruby / Ruby HEAD (MRI, Rubinius, & REE), install the following: ruby|ruby-head: emerge libiconv readline zlib openssl curl git libyaml sqlite libxslt libtool gcc autoconf automake bison m4 # For JRuby, install the following: jruby: emerge dev-java/sun-jdk dev-java/sun-jre-bin # For IronRuby, install the following: ironruby: emerge dev-lang/mono " elif [[ ! -z "$rvm_pacman_binary" ]] then printf "%b" " Additional Dependencies: # For Ruby / Ruby HEAD (MRI, Rubinius, & REE), install the following: ruby: pacman -Sy --noconfirm gcc patch curl zlib readline libxml2 libxslt git autoconf automake diffutils make libtool bison subversion # For JRuby, install the following: jruby: pacman -Sy --noconfirm jdk jre curl jruby-head: pacman -Sy apache-ant # For IronRuby, install the following: ironruby: pacman -Sy --noconfirm mono " elif [[ ! -z "$rvm_yum_binary" ]] then printf "%b" " Additional Dependencies: # For Ruby / Ruby HEAD (MRI, Rubinius, & REE), install the following: ruby: yum install -y gcc-c++ patch readline readline-devel zlib zlib-devel libyaml-devel libffi-devel openssl-devel make bzip2 autoconf automake libtool bison iconv-devel ## NOTE: For centos >= 5.4 iconv-devel is provided by glibc # For JRuby, install the following: jruby: yum install -y java " elif [[ ! -z "$rvm_zypper_binary" ]] then printf "%b" " Additional Dependencies: # For Ruby / Ruby HEAD (MRI, Rubinius, & REE), install the following: ruby: sudo zypper install -y patterns-openSUSE-devel_basis gcc-c++ bzip2 readline-devel zlib-devel libxml2-devel libxslt-devel libyaml-devel libopenssl-devel libffi45-devel libtool bison # For JRuby, install the following: jruby: sudo zypper install -y java-1_6_0-sun # Non-Oss repository required " else printf "%b" " Additional Dependencies: # For Ruby / Ruby HEAD (MRI, Rubinius, & REE), install the following with development headers: ruby: # gcc-c++ patch readline zlib libyaml iconv libxml2 libxslt libtool bison # For JRuby, install the following: jruby: # The SUN java runtime environment and development kit. # For IronRuby, install the following: ironruby: #The Mono Runtime and Development Platform (version 2.6 or greater is recommended). " fi elif [[ "SunOS" == "$system" ]] then version="$(uname -v)" if [[ "11.0" == "$version" ]] then # looks like Solaris 11 printf "%b" " RVM requirements for Solaris 11: # For Ruby / Ruby HEAD (MRI, Rubinius, & REE), install the following: ruby: pkg install text/gnu-patch developer/gcc-45 developer/library/lint system/header \\ system/library/math/header-math file/gnu-coreutils # For JRuby, install the following: jruby: # The Oracle java runtime environment and development kit. " elif [[ "$version" =~ ^oi ]] then # looks like OpenIndiana printf "%b" " RVM requirements for OpenIndiana # For Ruby / Ruby HEAD (MRI, Rubinius, & REE), install the following: ruby: pkg install text/gnu-patch runtime/gcc developer/library/lint system/header \\ system/library/math/header-math file/gnu-coreutils # For JRuby, install the following: jruby: # The Oracle java runtime environment and development kit. " else printf "%b" " RVM requirements for unrecognised Solaris system. # For Ruby / Ruby HEAD (MRI, Rubinius, & REE), install the following: ruby: you will need to install: gcc, gnu-patch, lint library, system header, system math header and gnu-coreutils. Check you package publisher(s) for installing these. # For JRuby, install the following: jruby: # The Oracle java runtime environment and development kit. " fi elif [[ "$MACHTYPE" == *darwin* ]] then if ! typeset -f __rvm_detect_xcode_version > /dev/null 2>&1 then source $rvm_path/scripts/functions/utility fi release="$( sw_vers -productName )" version="$( sw_vers -productVersion )" xcode_version="$( __rvm_detect_xcode_version )" : ${xcode_version:=0} printf "%b" " Notes for ${release} ${version}" if __rvm_version_compare $xcode_version -eq 0 then printf "%b" ", No Xcode. " else printf "%b" ", Xcode $xcode_version. " fi if __rvm_version_compare $xcode_version -ge 4.2 then printf "%b" " For MacRuby: Install LLVM first. " fi printf "%b" " For JRuby: Install the JDK. See http://developer.apple.com/java/download/ # Current Java version \"1.6.0_26\" For IronRuby: Install Mono >= 2.6 For Ruby 1.9.3: Install libksba # If using Homebrew, 'brew install libksba' To use an RVM installed Ruby as default, instead of the system ruby: rvm install 1.8.7 # installs patch 357: closest supported version rvm system ; rvm gemset export system.gems ; rvm 1.8.7 ; rvm gemset import system.gems # migrate your gems rvm alias create default 1.8.7 And reopen your terminal windows. " if __rvm_version_compare $xcode_version -gt 0 && __rvm_version_compare $xcode_version -lt 4.1 then printf "%b" " ** Please note that Xcode 3.x will *not* work on OS X Lion. For notes about Xcode 4.1 and later, see below: " fi printf "%b" " ${rvm_error_clr:-}Xcode and gcc${rvm_reset_clr:-}: Right now Ruby requires gcc to compile, but Xcode 4.2 and later no longer ship with gcc. Instead they ship with llvm-gcc (to which gcc is a symlink) and clang, neither of which are supported for building Ruby. Xcode 4.1 was the last version to ship gcc, which was /usr/bin/gcc-4.2. ${rvm_notify_clr:-}Xcode 4.1${rvm_reset_clr:-} and earlier: - Ruby will build fine. ${rvm_error_clr:-}Xcode 4.2${rvm_reset_clr:-} and later (including Command Line Tools for Xcode): - If you have gcc-4.2 (and friends) from an earlier Xcode version, Ruby will build fine. - If you don't have gcc-4.2, you have two options to get it: * Install apple-gcc42 from Homebrew * Install osx-gcc-installer ${rvm_notify_clr:-}Homebrew${rvm_reset_clr:-}: If you are using Homebrew, you can install the apple-gcc42 package from homebrew/dupes: brew tap homebrew/dupes brew install apple-gcc42 This can live side by side with an existing Xcode 4.2+ install or Command Line Tools for Xcode. ${rvm_notify_clr:-}osx-gcc-installer${rvm_reset_clr:-}: If you don't use Homebrew, you can download and install osx-gcc-installer: https://github.com/kennethreitz/osx-gccinstaller. ${rvm_error_clr:-}Warning${rvm_reset_clr:-}: Installing osx-gcc-installer on top of a recent Xcode is known to cause problems, so you must uninstall Xcode before installing osx-gcc-installer. Afterwards you may install Xcode 4.2+ or Command Line Tools for Xcode if you desire. ** NOTE: Currently, Node.js is having issues building with osx-gcc-installer. The only fix is to install Xcode over osxgcc-installer. " if (( UID == 0 )) || [[ "$rvm_path" == "/usr/local/rvm" ]] then printf "%b" " ${rvm_notify_clr:-}RVM Group Membership Management${rvm_reset_clr:-} - With Multi-User installations, the RVM installer automatically creates an 'rvm' group which, as the RVM documentation explains, administrators must add the users they wish to let use the RVM installation to. The call is made in the installer as: ${rvm_notify_clr:-}sudo dscl . -create /Groups/\$rvm_group_name gid \$gid${rvm_reset_clr:-} wherein RVM creates the gid by checking for the last assigned gid and adding 1. To physicially add a user to the group, administrators must use: ${rvm_notify_clr:-}sudo dscl localhost -append /Local/Default/Groups/rvm GroupMembership \$user_name${rvm_notify_clr:-} To check on group membership to the RVM group, administrators would execute the following: ${rvm_notify_clr:-}rvmsudo dscl localhost -read /Local/Default/Groups/rvm${rvm_reset_clr:-} Pay attention to the GroupMembership and PrimaryGroupID lines. This tells you who is in it, and the GID for the RVM group. Afterwards, should administrators wish to remove users from the group, they would execute: ${rvm_notify_clr:-}sudo dscl localhost -delete /Local/Default/Groups/rvm GroupMembership \$user_name${rvm_reset_clr:-} ${rvm_notify_clr:-}sudo dsmemberutil flushcache${rvm_reset_clr:-} This will keep the 'rvm' group, but remove the listed user from it. They can directly delete the rvm group with: ${rvm_notify_clr:-}sudo dscl . -delete /Groups/rvm && sudo dsmemberutil flushcache${rvm_reset_clr:-} without previously deleting users from the group, as well. This will completely remove the 'rvm' group from the system. Please note, the call to 'dsmemberutil flushcache' is required on both removal of the user from the group, and/or removal of the group directly because that membership is still cached locally until either reboot or sync with Directory Services. Allowing the group membership to stay in the user's 'groups' output does not mean the user is automatically re-added to the 'rvm' group should the group be subsequently be re-added. This means the user(s) end up erroneously showing they are part of the 'rvm' group even though they actually are not, if the call to 'dsmemberutil' is not made. By this we mean the 'groups' command will still show them a part of the 'rvm' group, even if the user logs out and then back in, due to caching. This applies to Tiger, Leopard, Snow Leopard, and Lion. Previous versions of the OS such as Cheetah/Puma, and Jaguar used 'nicl', a.k.a NetInfo, and not 'dscl'. " fi fi printf "%b" "\n" ) # Finish color resetting block 1.18.44. completion #!/usr/bin/env bash # bash completion for Ruby Version Manager (RVM) __rvm_comp() { typeset cur cur="${COMP_WORDS[COMP_CWORD]}" COMPREPLY=($(compgen -W "$1" -- "$cur")) return 0 } __rvm_subcommand() { typeset word subcommand c c=1 while [[ $c -lt $COMP_CWORD ]] ; do word="${COMP_WORDS[c]}" for subcommand in $1; do if [[ "$subcommand" == "$word" ]]; then echo "$subcommand" return fi done c=$((++c)) done } __rvm_rubies () { echo "$(rvm list strings) default system" } __rvm_gemsets () { echo "$(rvm gemset list | GREP_OPTIONS="" \grep -v gemset 2>/dev/null)" } __rvm_help_pages () { ls "$rvm_help_path" } __rvm_known () { # Strips comments and expands known patterns into each variation rvm list known | sed -e 's/#.*$//;' \ -e '/^$/d;' \ -e 's/^\[\(.*-\)\]\(.*\)\[\(-.*\)\]$/\1\2\3 \1\2 \2\3 \2/;' \ -e 's/^\[\(.*-\)\]\(.*\)$/\1\2 \2/;' \ -e 's/^\(.*\)\[\(-.*\)\]\[\(-.*\)\]$/\1\2\3 \1\2 \1/;' \ -e 's/^\(.*\)\[\(-.*\)\]$/\1\2 \1/ ' # | \tr ' ' "\n" | sort } _rvm_commands () { typeset cur cur=${COMP_WORDS[COMP_CWORD]} COMMANDS='\ version use reload implode update reset info debug\ install uninstall reinstall remove\ ruby gem rake tests specs monitor gemset\ gemdir srcdir fetch list package notes snapshot\ help' case "${cur}" in -*) _rvm_opts ;; *) __rvm_comp "$COMMANDS $(__rvm_rubies)" ;; esac } _rvm_opts () { RVM_OPTS='\ -h\ --help\ -v\ --version\ -l --level\ --bin\ --gems\ --archive\ --patch -S\ -e\ -G\ -C\ --configure\ --nice\ --ree-options\ --head\ --rubygems\ --default\ --debug\ --trace\ --force\ --summary\ --latest\ --docs\ --reconfigure --create' __rvm_comp "$RVM_OPTS" } _rvm_use () { typeset _command _command="${COMP_WORDS[COMP_CWORD-2]}" case "${_command}" in gemset) __rvm_comp "$(__rvm_gemsets)" ;; *) __rvm_comp "$(__rvm_rubies)" ;; esac } _rvm_gemset () { typeset subcommand subcommands subcommands="use create" subcommand="$(__rvm_subcommand "$subcommands")" if [[ -z "$subcommand" ]]; then __rvm_comp "$subcommands" return fi } _rvm_help () { __rvm_comp "$(__rvm_help_pages)" } _rvm_install () { __rvm_comp "$(__rvm_known)" } _rvm () { typeset prev prev=${COMP_WORDS[COMP_CWORD-1]} case "${prev}" in use) _rvm_use ;; gemset) _rvm_gemset ;; help) _rvm_help ;; install) _rvm_install ;; *) _rvm_commands ;; esac return 0 } complete -o default -o nospace -F _rvm rvm 1.18.45. selector_gemsets #!/usr/bin/env bash __rvm_gemset_handle_default() { rvm_gemset_name="@${rvm_gemset_name:-}@" rvm_gemset_name="${rvm_gemset_name/@default@/@@}" rvm_gemset_name="${rvm_gemset_name#@}" rvm_gemset_name="${rvm_gemset_name%@}" } __rvm_gemset_select_cli_validation() { typeset orig_gemset if ! builtin command -v gem > /dev/null then rvm_log "'gem' command not found, cannot select a gemset." return 0 fi orig_gemset="${rvm_gemset_name:-}" __rvm_gemset_handle_default # No longer defaulting to 'sticky' gem sets. # Set 'rvm_sticky_flag=1' in ~/.rvmrc to enable. if [[ -z "${rvm_gemset_name:-}" && "$orig_gemset" != "default" && ${rvm_sticky_flag:-0} -eq 1 ]] then if [[ -n "${rvm_ruby_gem_home:-}" ]] then rvm_gemset_name="$rvm_ruby_gem_home" elif [[ -n "${GEM_HOME:-}" ]] then rvm_gemset_name="$GEM_HOME" fi rvm_gemset_name="${rvm_gemset_name##*/}" rvm_gemset_name="${rvm_gemset_name#*${rvm_gemset_separator:-"@"}}" fi if [[ -z "${rvm_ruby_string:-}" && -n "${GEM_HOME:-}" && -n "${GEM_HOME%@*}" ]] then rvm_ruby_string="${GEM_HOME%@*}" rvm_ruby_string="${rvm_ruby_string##*/}" fi if [[ -z "${rvm_ruby_string:-}" ]] then rvm_error "Gemsets can not be used with non rvm controlled rubies (currently)." return 3 fi } __rvm_gemset_select_only() { rvm_ruby_gem_home="${rvm_gems_path:-"$rvm_path/gems"}/$rvm_ruby_string" : rvm_ignore_gemsets_flag:${rvm_ignore_gemsets_flag:=0}: if (( rvm_ignore_gemsets_flag )) then rvm_ruby_global_gems_path="${rvm_ruby_gem_home}" rvm_ruby_gem_path="${rvm_ruby_gem_home}" rvm_gemset_name="" else rvm_ruby_global_gems_path="${rvm_ruby_gem_home}${rvm_gemset_separator:-"@"}global" __rvm_gemset_handle_default [[ -z "$rvm_gemset_name" ]] || rvm_ruby_gem_home="${rvm_ruby_gem_home}${rvm_gemset_separator:-"@"}${rvm_gemset_name}" if [[ "$rvm_gemset_name" == "global" ]] then rvm_ruby_gem_path="${rvm_ruby_gem_home}" else rvm_ruby_gem_path="${rvm_ruby_gem_home}:${rvm_ruby_global_gems_path}" fi fi if [[ -n "${rvm_gemset_name}" ]] then rvm_env_string="${rvm_ruby_string}@${rvm_gemset_name}" else rvm_env_string=${rvm_ruby_string} fi } __rvm_gemset_select_validation() { # If the gemset does not exist, then notify the user as such and abort the action. if [[ ! -d "${rvm_ruby_gem_home}" ]] then if (( ${rvm_gemset_create_on_use_flag:=0} == 0 && ${rvm_create_flag:=0} == 0 && ${rvm_delete_flag:=0} == 0 )) then rvm_expected_gemset_name="${rvm_gemset_name}" rvm_gemset_name="" __rvm_gemset_select_only return 2 fi elif (( ${rvm_delete_flag:=0} == 1 )) then return 4 fi } __rvm_gemset_select_ensure() { \mkdir -p "$rvm_ruby_gem_home" if __rvm_using_gemset_globalcache && [[ ! -L "$rvm_ruby_gem_home/cache" ]] then : rvm_gems_cache_path:${rvm_gems_cache_path:=${rvm_gems_path:-"$rvm_path/gems"}/cache} \mv "$rvm_ruby_gem_home/cache/"*.gem "$rvm_gems_cache_path/" 2>/dev/null __rvm_rm_rf "$rvm_ruby_gem_home/cache" \ln -fs "$rvm_gems_cache_path" "$rvm_ruby_gem_home/cache" fi } # Select a gemset based on CLI set options and environment. __rvm_gemset_select_cli() { __rvm_gemset_select_cli_validation && __rvm_gemset_select } __rvm_gemset_select() { __rvm_gemset_select_only && __rvm_gemset_select_validation && __rvm_gemset_select_ensure } # Use a gemset specified by 'rvm_ruby_gem_home' __rvm_gemset_use() { if __rvm_gemset_select_cli then rvm_log "Using $rvm_ruby_string with gemset ${rvm_gemset_name:-default}" __rvm_use # Now ensure the selection takes effect for the environment. else if [[ ! -d "$rvm_ruby_gem_home" || -n "${rvm_expected_gemset_name}" ]] then if (( ${rvm_gemset_create_on_use_flag:=0} == 1 || ${rvm_create_flag:=0} == 1 )) then rvm_warn "gemset $rvm_gemset_name is not existing, creating." "$rvm_scripts_path/gemsets" create "$rvm_gemset_name" else rvm_error "Gemset '${rvm_expected_gemset_name}' does not exist, 'rvm gemset create ${rvm_expected_gemset_name}' first, or append '--create'." return 2 fi else rvm_error "Gemset was not given.\n Usage:\n rvm gemset use <gemsetname>\n" return 1 fi fi } __rvm_gemset_clear() { export rvm_gemset_name rvm_gemset_name="" __rvm_use # Now ensure the selection takes effect for the environment. } 1.18.46. cd #!/usr/bin/env bash # Source a .rvmrc file in a directory after changing to it, if it exists. To # disable this feature, set rvm_project_rvmrc=0 in /etc/rvmrc or $HOME/.rvmrc if (( ${rvm_project_rvmrc:-1} > 0 )) then __rvm_setup_cd() { # try to use smartcd function, fallback to builtin typeset __cd_prefix __command if typeset -f smartcd >/dev/null 2>/dev/null then __cd_prefix="smartcd" else __cd_prefix="builtin" fi __rvm_after_cd() { typeset rvm_hook rvm_hook="after_cd" if [[ -n "${rvm_scripts_path:-}" || -n "${rvm_path:-}" ]] then source "${rvm_scripts_path:-$rvm_path/scripts}/hook" fi } __rvm_setup_cd_function() { typeset __cd_prefix __command __cd_prefix=$1 __command=$2 eval " ${__command}(){ if ${__cd_prefix} ${__command} \"\$@\" then [[ -n \"\${rvm_current_rvmrc:-""}\" && \"\$*\" == \".\" ]] && rvm_current_rvmrc=\"\" || true __rvm_do_with_env_before __rvm_project_rvmrc __rvm_after_cd __rvm_do_with_env_after return 0 else return \$? fi }" } if [[ -n "${ZSH_VERSION:-}" ]] then autoload is-at-least if is-at-least 4.3.4 >/dev/null 2>&1; then # On zsh, use chpwd_functions export -a chpwd_functions chpwd_functions=( "${chpwd_functions[@]}" __rvm_do_with_env_before __rvm_project_rvmrc __rvm_after_cd __rvm_do_with_env_after ) else for __command in cd popd pushd do __rvm_setup_cd_function "${__cd_prefix}" "${__command}" done fi else for __command in cd popd pushd do __rvm_setup_cd_function "${__cd_prefix}" "${__command}" done fi } __rvm_setup_cd # This functionality is opt-in by setting rvm_cd_complete_flag=1 in ~/.rvmrc # Generic bash cd completion seems to work great for most, so this is only # for those that have some issues with that. if (( ${rvm_cd_complete_flag:-0} == 1 )) then # If $CDPATH is set, bash should tab-complete based on directories in those paths, # but with the cd function above, the built-in tab-complete ignores $CDPATH. This # function returns that functionality. _rvm_cd_complete () { typeset directory current matches item index sep sep="${IFS}" export IFS IFS=$'\n' COMPREPLY=() current="${COMP_WORDS[COMP_CWORD]}" if [[ -n "$CDPATH" && ${current:0:1} != "/" ]] ; then index=0 # The change to IFS above means that the \tr below should replace ':' # with a newline rather than a space. A space would be ignored, breaking # TAB completion based on CDPATH again for directory in $(printf "%b" "$CDPATH" | \tr -s ':' '\n') ; do for item in $( compgen -d "$directory/$current" ) ; do COMPREPLY[index++]=${item#$directory/} done done else COMPREPLY=( $(compgen -d ${current}) ) fi IFS="${sep}"; } complete -o bashdefault -o default -o filenames -o dirnames -o nospace -F _rvm_cd_complete cd fi fi 1.18.47. help #!/usr/bin/env bash rvm_base_except="selector" source "$rvm_scripts_path/base" args=($*) _command="${args[$__array_start]}" args[$__array_start]="" args=(${args[@]}) action="${args[$array_start]}" args[$__array_start]="" args=(${args[@]}) if [[ -n "$_command" && -s "${rvm_help_path}/${_command}" ]] ; then if [[ -n "$action" && -s "${rvm_help_path}/${_command}/${action}" ]] ; then __rvm_pager_or_cat_v "${rvm_help_path}/${_command}/${action}" else __rvm_pager_or_cat_v "${rvm_help_path}/${_command}" fi else __rvm_pager_or_cat_v "${rvm_path:-$HOME/.rvm}/README" | sed '1,2d' rvm_log " Commands available with 'rvm help': $(builtin cd "${rvm_help_path}" ; find . -maxdepth 1 -mindepth 1 -type f -print | \tr "\n" ' ' | sed -e 's#./##g') " fi rvm_log " For additional information please visit RVM's documentation website: https://rvm.io/ If you still cannot find what an answer to your question, find me 'wayneeseguin' in #rvm on irc.freenode.net: http://webchat.freenode.net/?channels=rvm " exit $? 1.18.48. db #!/usr/bin/env bash usage() { printf "%b" " Usage: db database_file {{key}} {{value}} # set db database_file {{key}} # get db database_file {{key}} unset # unset " >&2 } if [[ -f "$1" ]] then database_file="$1" shift if [[ ! -f "$database_file" ]] then directory=$(dirname "$database_file") [[ -d "$directory" ]] || mkdir -p "$directory" touch "$database_file" fi else printf "%b" "\n\nDatabase file $1 does not exist.\n\n" >&2 exit 1 fi key="$1" shift if [[ -z "$key" ]] then usage exit 1 else if (( ${escape_flag:-0} )) then escaped_key="$(\printf "%b" "$key" | \sed -e 's#\\#\\#g' -e 's#/#\\/#g' -e 's#\.#\.#g')" else escaped_key="$key" fi value="$*" if [[ "unset" == "$value" || "delete" == "$value" ]] then \sed -e "s#^$escaped_key=.*\$##" -e '/^$/d' "$database_file" \ > "$database_file.new" mv "$database_file.new" "$database_file" else if [[ -z "$value" ]] then # get [[ -s "${database_file}" ]] || exit 0 # File is empty, nothing to get. \awk -F= '/^'"$escaped_key"'=/' "$database_file" \ | \sed -e "s#^$escaped_key=##" -e '/^$/d' else # set \sed -e "s#^$escaped_key=.*\$##" -e '/^$/d' "$database_file" > "$database_file.new" mv "$database_file.new" "$database_file" if [[ -z "$(awk -F= "/^'"$escaped_key"'=/{print $2}" "$database_file")" ]] then # append echo "$escaped_key=$value" >> "$database_file" else # overwrite \sed -i.tmp "s#^$escaped_key=.*\$#$escaped_key=$value#" "$database_file" > "$database_file.new" mv "$database_file.new" "$database_file" fi fi fi fi 1.18.49. array #!/usr/bin/env bash if [[ -n "${ZSH_VERSION:-}" ]] then __array_start=1 else __array_start=0 fi # Usage: contains "a_string" "${an_array[@]}" array_contains() { typeset pattern index typeset -a list pattern="$1" shift list=("$@") for index in "${!list[@]}" do [[ ${list[index]} = $pattern ]] && { echo $index ; return 0 ; } done echo -1 return 1 } array_length() { array=$1 eval "length=\${#${array}[*]}" echo $length return $length } array_push() { array=$1 item=$2 # TODO: allow loop over more arguments. eval "index=\$((\${#${array}[*]} + $__array_start))" eval "${array}[${index}]=${item}" } 1.18.50. cleanup #!/usr/bin/env bash rvm_base_except="selector" source "$rvm_scripts_path/base" usage() { printf "%b" " Usage: rvm cleanup {all,archives,repos,sources,logs} Description: Cleans up the directory tree for the specified item. " return 0 } cleanup() { typeset cleanup_type current_path entry for cleanup_type in $@ do current_path="${rvm_path}/${cleanup_type}" if [[ -n "$current_path" && -d "$current_path" && "$current_path" != "/" ]] then rvm_log "Cleaning up rvm directory '$current_path'" for entry in "$current_path"/* do case $entry in (*\*) continue ;; # skip empty dirs esac chmod -R u+w "$entry" __rvm_rm_rf "$entry" done fi done return 0 } case "$1" in all) cleanup archives repos src log tmp ;; archives) cleanup archives ;; repos) cleanup repos ;; sources) cleanup src ;; logs) cleanup log ;; tmp) cleanup tmp ;; help) usage ;; *) usage ; exit 1;; esac exit $? 1.18.51. patches #!/usr/bin/env bash # General tools for manipulating patches # and dealing with patches. # Returns the path used to look for a patch given a specific name. __rvm_patch_lookup_path() { echo "/" [[ -n "${rvm_patch_original_pwd:-""}" ]] && echo "$rvm_patch_original_pwd/" echo "$PWD/" __rvm_ruby_string_paths_under "$rvm_patches_path" | sed 's/$/\//' | sort -r return $? } __rvm_expand_patch_name() { typeset name expanded_patch_name name="${1:-""}" [[ -z "$name" ]] && return 0 expanded_patch_name="$(rvm_ruby_string="${rvm_ruby_string}" "$rvm_scripts_path/patchsets" show "$name")" if [[ "$?" == "0" ]] then echo "${expanded_patch_name}" elif [[ "$name" != "default" ]] then echo "$name" fi return 0 } # Return the full patch for a given patch. __rvm_lookup_full_patch_path() { typeset extension patch_path directory directories # Absolute path, pwd and then finally the rvm patches path. directories=($(__rvm_patch_lookup_path)) for directory in "${directories[@]}" ; do for extension in {"",.patch,.diff}; do patch_path="${directory}${1}${extension}" # -s reports directories too - so additional check -f needed if [[ -s "$patch_path" && -f "$patch_path" ]]; then echo "$patch_path" return 0 fi done done return 0 } 1.18.52. snapshot #!/usr/bin/env bash sys=$( uname -s ) if [[ "${sys}" == AIX ]] ; then name_opt=-name else name_opt=-iname fi unset GREP_COLOR unset GREP_OPTIONS source "$rvm_scripts_path/base" __error_on_result() { if [[ "$1" -gt 0 ]]; then rvm_error "$2 - Aborting now." return 0 else return 1 fi } snapshot_save() { typeset snapshot_temp_path snapshot_ruby_name_file \ snapshot_alias_name_file snapshot_installable_file \ snapshot_primary_ruby snapshot_ruby_order destination_path if [[ -z "$1" ]] then printf "%b" " Usage: rvm snapshot save name Description: Saves a snapshot describing the rvm installation to <name>.tar.gz in the current working directory.\ " >&2 return 1 fi # Create the temporary directory. snapshot_temp_path="${rvm_tmp_path}/$$-snapshot" __rvm_rm_rf "$snapshot_temp_path" mkdir -p "$snapshot_temp_path" rvm_log "Backing up a list of aliases" cp "$rvm_path/config/alias" "$snapshot_temp_path/" rvm_log "Backing up your user preferences" cp "$rvm_user_path/db" "$snapshot_temp_path/" rvm_log "Backing up your installed packages" sed -e 's/-//' -e 's/^lib//' < "$rvm_path/config/pkg" | awk -F= '{print $1}' | sort | uniq > "$snapshot_temp_path/pkg" rvm_log "Backing up all of your gemsets" mkdir -p "$snapshot_temp_path/gems" ( builtin cd "$snapshot_temp_path/gems" for snapshot_gemset in $("$rvm_scripts_path/list" gemsets strings) ; do __rvm_become "$snapshot_gemset" ; result="$?" __error_on_result "$result" "Error becoming ruby $snapshot_gemset" && return "$result" "$rvm_scripts_path/gemsets" export "${snapshot_gemset}.gems" >/dev/null ; result="$?" __error_on_result "$result" "Error exporting gemset contents for $snapshot_gemset" && return "$result" mkdir -p "./$snapshot_gemset/" [[ -d "$GEM_HOME/cache/" ]] && \cp -R "$GEM_HOME/cache/" "./$snapshot_gemset/" done ) rvm_log "Backing up all of your installed rubies" printf "%b" "#!/usr/bin/env bash\n\nset -e\n\n" > "$snapshot_temp_path/install-rubies.sh" echo "source \"\$rvm_scripts_path/rvm\" || true" >> "$snapshot_temp_path/install-rubies.sh" snapshot_ruby_name_file="${rvm_tmp_path}/$$-rubies" snapshot_alias_name_file="${rvm_tmp_path}/$$-aliases" snapshot_installable_file="${rvm_tmp_path}/$$-installable" "$rvm_scripts_path/alias" list | awk -F ' => ' '{print $1}' | sort | uniq 2>/dev/null > "$snapshot_alias_name_file" "$rvm_scripts_path/list" strings | \tr ' ' '\n' | sort | uniq > "$snapshot_ruby_name_file" comm -2 -3 "$snapshot_ruby_name_file" "$snapshot_alias_name_file" > "$snapshot_installable_file" __rvm_rm_rf "$snapshot_ruby_name_file" __rvm_rm_rf "$snapshot_alias_name_file" snapshot_primary_ruby="$(GREP_OPTIONS="" \grep '^\(ree\|ruby-1.8.7\)' < "$snapshot_installable_file" | \grep -v '-head$' | sort -r | head -n1)" snapshot_ruby_order="$snapshot_primary_ruby $(GREP_OPTIONS="" \grep -v "$snapshot_primary_ruby" < "$snapshot_installable_file")" for snapshot_ruby_name in $snapshot_ruby_order do snapshot_install_command="$(__rvm_recorded_install_command "$snapshot_ruby_name")" if [[ -n "$snapshot_install_command" ]] then echo "rvm install $snapshot_install_command" | sed "s#$rvm_path#'\\\"\$rvm_path\\\"'#" >> "$snapshot_temp_path/install-rubies.sh" else __rvm_become "$snapshot_ruby_name" ruby "$rvm_path/lib/rvm/install_command_dumper.rb" >> "$snapshot_temp_path/install-rubies.sh" fi unset snapshot_install_command done unset snapshot_ruby_name snapshot_primary_ruby __rvm_rm_rf "$snapshot_installable_file" rvm_log "Compressing snapshotting" destination_path="$PWD" ( builtin cd "$snapshot_temp_path" __rvm_rm_rf "$destination_path/$1.tar.gz" $rvm_tar_command czf "$destination_path/$1.tar.gz" . result="$?" __error_on_result "$result" "Error creating archive $destination_path/$1.tar.gz" && return "$result" ) rvm_log "Cleaning up" __rvm_rm_rf "$snapshot_temp_path" rvm_log "Snapshot complete" } snapshot_load() { typeset package_info snapshot_archive snapshot_temp_path \ alias_name alias_ruby export rvm_create_flag if [[ -z "$1" ]] then echo "Usage: rvm snapshot load name" >&2 echo "Loads a snapshot from <name>.tar.gz in the current directory." >&2 return 1 fi snapshot_archive="$PWD/$(echo "$1" | sed 's/.tar.gz$//').tar.gz" if ! [[ -s "$snapshot_archive" ]] then echo "The provides snapshot '$(basename "$snapshot_archive")' doesn't exist." >&2 return 1 fi snapshot_temp_path="${rvm_tmp_path}/$$-snapshot" __rvm_rm_rf "$snapshot_temp_path" \mkdir -p "$snapshot_temp_path" rvm_log "Extracting snapshot" ( builtin cd "$snapshot_temp_path" $rvm_tar_command xzf "$snapshot_archive" result="$?" __error_on_result "$result" "Error extracting the archive '$snapshot_archive'" && return "$result" ) rvm_log "Restoring user settings" \cp -f "$snapshot_temp_path/db" "$rvm_user_path/db" rvm_log "Installing rvm-managed packages" for snapshot_package in $(cat "$snapshot_temp_path/pkg") do "$rvm_scripts_path/package" install "$snapshot_package" result="$?" __error_on_result "$result" "Error installing package '$snapshot_package'" && return "$result" done unset snapshot_package rvm_log "Installing rubies" chmod +x "$snapshot_temp_path/install-rubies.sh" sed -i'' '1 s/#!\/usr\/bin\/env bash -e/#!\/usr\/bin\/env bash\n\nset -e/' "$snapshot_temp_path/install-rubies.sh" "$snapshot_temp_path/install-rubies.sh" result="$?" __error_on_result "$result" "Error importing rubies." && return "$result" rvm_create_flag=1 rvm_log "Setting up gemsets" ( builtin cd "$snapshot_temp_path/gems" gems=($(find . -mindepth 0 -maxdepth 0 -type f "${name_opt}" '*.gems' | sed 's/.gems$//')) for snapshot_gemset in "${gems[@]//.\/}" do __rvm_become "$snapshot_gemset" result="$?" __error_on_result "$result" \ "Error becoming '$snapshot_gemset'" && return "$result" mkdir -p "$GEM_HOME/cache/" cp -Rf "$snapshot_gemset/" "$GEM_HOME/cache/" result="$?" __error_on_result "$result" \ "Error copying across cache for $snapshot_gemset" && return "$result" "$rvm_scripts_path/gemsets" import "$snapshot_gemset" >/dev/null 2>&1 result="$?" __error_on_result "$result" \ "Error importing gemset for $snapshot_gemset" && return "$result" done ) rvm_log "Restoring aliases" while read -r package_info do # Note: this assumes an '=' int the input... alias_name="${package_info/=*}" alias_ruby="${package_info/*=}" "$rvm_scripts_path/alias" create "$alias_name" "$alias_ruby" if [[ "$alias_name" == "default" ]] then (source "$rvm_scripts_path/rvm" && rvm use "$alias_ruby" --default) >/dev/null 2>&1 result="$?" __error_on_result "$result" "Error setting default to $alias_ruby" && return "$result" fi done < "$snapshot_temp_path/alias" rvm_log "Cleaning up load process" __rvm_rm_rf "$snapshot_temp_path" rvm_log "Loaded snapshot from $(basename "$snapshot_archive")" } snapshot_usage() { echo "Usage: rvm snapshot {save,load} file" >&2 return 1 } args=($*) action="${args[0]}" args="$(echo ${args[@]:1})" # Strip trailing / leading / extra spacing. case "$action" in save) snapshot_save "$args" ;; load) snapshot_load "$args" ;; *) snapshot_usage ;; esac exit $? 1.18.53. cli #!/usr/bin/env bash __rvm_usage() { __rvm_pager_or_cat_v "${rvm_path:-$HOME/.rvm}/README" } __rvm_run_script() { "$rvm_scripts_path/${1:-"$rvm_action"}" "${rvm_ruby_args[@]}" } __rvm_parse_args() { typeset _string export rvm_ruby_string rvm_action="${rvm_action:-""}" rvm_parse_break=0 if [[ " $* " =~ " --trace " ]] then echo "$@" __rvm_version fi while [[ -n "$next_token" ]] do rvm_token="$next_token" if (( $# > 0 )) then next_token="$1" shift else next_token="" fi case "$rvm_token" in [[:alnum:]]*|@*) # Commands, Rubies and Gemsets case "$rvm_token" in use) rvm_action="$rvm_token" rvm_verbose_flag=1 if [[ "ruby" == "$next_token" ]] then if (( $# > 0 )) then next_token="$1" shift else next_token="" fi fi ;; install|uninstall|reinstall|try_install) export ${rvm_token}_flag=1 rvm_action=$rvm_token _string="$*" if [[ "${_string} " =~ "-- " ]] then export rvm_install_args="${_string//*-- /}" fi ;; gemset) rvm_action=$rvm_token rvm_ruby_gem_home="${GEM_HOME:-""}" if [[ "$next_token" == "--create" ]] then rvm_create_flag=1 next_token="${1:-}" (( $# == 0 )) || shift elif [[ " $* " =~ " --create " ]] then rvm_create_flag=1 fi if [[ -z "$next_token" ]] then rvm_ruby_args=("help") elif [[ "clear" == "$next_token" ]] then __rvm_gemset_clear rvm_ruby_args=("clear") elif [[ "use" == "$next_token" ]] then rvm_use_flag=1 rvm_ruby_args=("$next_token" "$@") rvm_gemset_name="$next_token" if (( $# > 0 )) then next_token="$1" shift else next_token="" fi if [[ -n "$next_token" ]] ; then rvm_gemset_name="$next_token" ; else rvm_gemset_name="" ; fi if [[ -z "${rvm_gemset_name:-}" ]] then rvm_error "Gemset was not given.\n return 1 fi Usage:\n rvm gemset use <gemsetname>\n" case "$rvm_gemset_name" in *${rvm_gemset_separator:-"@"}*) rvm_ruby_string="${rvm_gemset_name%%${rvm_gemset_separator:-"@"}*}" rvm_gemset_name="${rvm_gemset_name##*${rvm_gemset_separator:-"@"}}" if [[ "${rvm_ruby_string:-""}" != "${rvm_gemset_name:-""}" ]] ; then rvm_ruby_string="$rvm_ruby_string${rvm_gemset_separator:-"@"}$rvm_gemset_name" fi rvm_ruby_gem_home="$rvm_ruby_gem_home${rvm_gemset_separator:-"@"}$rvm_gemset_name" ;; esac elif [[ "delete" == "$next_token" ]] then rvm_delete_flag=1 rvm_ruby_args=("$next_token" "$@") if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi rvm_gemset_name="$next_token" if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi case "$rvm_gemset_name" in *${rvm_gemset_separator:-"@"}*) rvm_ruby_string="${rvm_gemset_name%%${rvm_gemset_separator:-"@"}*}" rvm_gemset_name="${rvm_gemset_name##*${rvm_gemset_separator:-"@"}}" if [[ "$rvm_ruby_string" != "$rvm_gemset_name" ]] ; then rvm_ruby_string="$rvm_ruby_string${rvm_gemset_separator:-"@"}$rvm_gemset_name" fi rvm_ruby_gem_home="$rvm_ruby_gem_home${rvm_gemset_separator:-"@"}$rvm_gemset_name" ;; esac else if [[ "${rvm_ruby_string:-""}" != "${rvm_gemset_name:-""}" ]] ; then __rvm_ruby_string ; rvm_ruby_args=("$next_token" "$@") fi : rvm_ruby_args:${rvm_ruby_args[*]}: rvm_parse_break=1 ;; gemdir|gempath|gemhome) rvm_ruby_args=("$rvm_token") rvm_action="gemset" rvm_gemdir_flag=1 if [[ "system" == "$next_token" ]] then rvm_system_flag=1 if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi fi if [[ "user" == "$next_token" ]] then rvm_user_flag=1 if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi fi ;; pkg) rvm_action="$rvm_token" if [[ "$next_token" == "--only-path" ]] then shift rvm_only_path_flag=1 fi rvm_ruby_args=("$next_token" "$@") rvm_parse_break=1 ;; fi system|default) rvm_action=${rvm_action:-use} rvm_ruby_interpreter="$rvm_token" rvm_ruby_string="$rvm_token" rvm_ruby_strings="$rvm_token" ;; do|exec|gem|rake|ruby) if [[ "$rvm_token" == "ruby" ]] && [[ "$rvm_action" == "install" || "$rvm_action" == "use" ]] then rvm_ruby_string=ruby rvm_ruby_strings=ruby continue fi if [[ -z "$next_token" ]] then rvm_action="error" rvm_error_message="'rvm $rvm_token' must be followed by arguments." break fi rvm_action="do" rvm_parse_break=1 case "$rvm_token" in do|exec) # deprecation for exec removed after discsussion with Wayne rvm_ruby_args=("$next_token" "$@") ;; *) # TODO: deprecation issued on 2011.10.11, for RVM 1.9.0 rvm_warn "Please note that \`rvm $rvm_token ...\` is only an alias to \`rvm do $rvm_token ...\`,\n"\ "it might work different as in earlier versions of RVM and will be shortly removed!\n"\ "Also note that you do not have to prefix every command with \`rvm\`, they should just work by itself." rvm_ruby_args=("$rvm_token" "$next_token" "$@") ;; esac ;; fetch|version|srcdir|reset|debug|reload|update|monitor|notes|implode|seppuku|question|answer|env|unexport|requirements|autom ount) rvm_action=$rvm_token ;; mount) rvm_action=$rvm_token while [[ -n "${next_token:-}" ]] && [[ -x "${next_token:-}" || -d "${next_token:-}" ]] do rvm_ruby_args=("$next_token" "${rvm_ruby_args[@]}") if (( $# > 0 )) then next_token="$1" shift else next_token="" fi done ;; rm|remove) rvm_action="remove" rvm_remove_flag=1 ;; # Can likely remove this due to the *) case default) # No-op ;; inspect|ls|list|info|strings|get|current) if [[ "ls" == "$rvm_action" ]]; then rvm_action="list" ; fi rvm_action="$rvm_token" rvm_ruby_args=("$next_token" "$@" ) rvm_parse_break=1 ;; docs|alias|rubygems|cleanup|tools|disk-usage|snapshot|repair|migrate|upgrade|cron) rvm_action="$rvm_token" rvm_ruby_args=("$next_token" "$@") rvm_parse_break=1 ;; user) rvm_action="tools" rvm_ruby_args=("$rvm_token" "$next_token" "$@") rvm_parse_break=1 ;; load-rvmrc) rvm_action="rvmrc" rvm_ruby_args=("load" "$next_token" "$@") rvm_parse_break=1 ;; rvmrc) rvm_action="rvmrc" rvm_ruby_args=("$next_token" "$@") rvm_parse_break=1 ;; benchmark|bench) rvm_action="benchmark" ;; specs|tests) rvm_action="rake" rvm_ruby_args=("${rvm_token/%ss/s}") ;; export) if [[ ! -z "$next_token" ]] ; then rvm_export_args="$next_token$@" rvm_action="export" rvm_parse_break=1 else rvm_action="error" rvm_error_message="rvm export must be followed by a NAME=VALUE argument" fi ;; group) rvm_action="group" rvm_ruby_args=("$next_token" "$@") rvm_parse_break=1 ;; alt*) rvm_action="help" rvm_ruby_args=("alt.md") rvm_parse_break=1 ;; help|usage) rvm_action="help" rvm_ruby_args=("$next_token" "$@") rvm_parse_break=1 ;; wrapper) rvm_action="wrapper" rvm_ruby_string="$next_token" ; rvm_wrapper_name="$1" (( $# == 0 )) || shift rvm_ruby_args=("$@") # list of binaries, or empty rvm_parse_break=1 ;; rtfm|RTFM) rvm_action="rtfm" rvm_parse_break=1 ;; reboot|damnit|wtf|argh|BOOM|boom|wth) $rvm_action="reboot" ;; *) if [[ "$rvm_token" == "in" ]] then rvm_token="${next_token}" next_token="${1:-}" (( $# == 0 )) || shift if __rvm_project_dir_check "$rvm_token" then export rvm_in_flag="$rvm_token" __rvm_rvmrc_tools try_to_read_ruby $rvm_token else export "rvm_in_flag"=1 fi elif [[ -n "$rvm_token" ]] then # TODO: Middle should be convertable to a case statement for further # efficiency only have to deal with the first and last parts. if [[ "gemset" == "$rvm_action" ]] then case "$rvm_token" in *${rvm_gemset_separator:-"@"}*) rvm_gemset_name="${rvm_token/*${rvm_gemset_separator:-"@"}/}" rvm_ruby_string="${rvm_token/${rvm_gemset_separator:-"@"}*/}" ;; *.gems) rvm_file_name="${rvm_token/.gems/}.gems" # Account for possible .gems.gems ;; *) rvm_gemset_name="${rvm_token/.gems/}" rvm_file_name="$rvm_gemset_name.gems" ;; esac else case "$rvm_token" in *,*) rvm_ruby_strings="$rvm_token" if [[ -z "${rvm_action:-""}" ]] then rvm_action="ruby" # Not sure if we really want to do this but we'll try it out. fi ;; ${rvm_gemset_separator:-"@"}*) rvm_action="${rvm_action:-use}" rvm_gemset_name="${rvm_token/*${rvm_gemset_separator:-"@"}/}" rvm_ruby_string="${rvm_ruby_string:-""}" rvm_ruby_strings="${rvm_ruby_string}${rvm_gemset_separator:-"@"}${rvm_gemset_name}" ;; *${rvm_gemset_separator:-"@"}*) rvm_action="${rvm_action:-use}" gemset_name="${rvm_token/*${rvm_gemset_separator:-"@"}/}" rvm_ruby_string="$rvm_token" rvm_ruby_strings="$rvm_token" ;; *+*) rvm_action="${rvm_action:-use}" rvm_ruby_alias="${rvm_token/*+/}" rvm_ruby_string="${rvm_token/+*/}" rvm_ruby_strings="$rvm_ruby_string" ;; *-*) rvm_action="${rvm_action:-use}" rvm_ruby_string="$rvm_token" rvm_ruby_strings="$rvm_token" ;; +([[:digit:]]).+([[:digit:]])*) rvm_action="${rvm_action:-use}" rvm_ruby_string="$rvm_token" rvm_ruby_strings="$rvm_token" ;; jruby*|ree*|kiji*|macruby*|rbx*|rubinius*|goruby|ironruby*|default*|maglev*|tcs*|all) rvm_action="${rvm_action:-use}" if [[ "rubinius" == "$rvm_token" ]] ; then rvm_token="rbx"; fi rvm_ruby_interpreter="$rvm_token" rvm_ruby_string="$rvm_token" rvm_ruby_strings="$rvm_token" if match "$next_token" "[0-9].[0-9]*" ; then rvm_ruby_version=$next_token if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi fi ;; *.rb) # we have a specified ruby script rvm_ruby_args=("$rvm_token") rvm_ruby_file="$rvm_token" if [[ -z "${rvm_action:-""}" || "$rvm_action" == "use" ]]; then rvm_action="ruby" fi ;; *) if [[ -L "$rvm_rubies_path/$rvm_token" ]] ; then # Alias rvm_ruby_string=$rvm_token rvm_ruby_strings="$rvm_token" rvm_action="${rvm_action:-use}" elif __rvm_project_dir_check "$rvm_token" then __rvm_rvmrc_tools try_to_read_ruby $rvm_token else rvm_action="error" rvm_error_message="Unrecognized command line argument: '$rvm_token'" fi ;; esac fi else rvm_action="error" rvm_error_message="Unrecognized command line argument(s): '$rvm_token $@'" fi if [[ "error" == "${rvm_action:-""}" ]] ; then break ; fi ;; esac ;; -*) # Flags case "$rvm_token" in -S) rvm_action="ruby" rvm_ruby_args=("$rvm_token" "$next_token" "$@") rvm_parse_break=1 ;; -e) rvm_action="ruby" IFS="\n" rvm_ruby_args=("$rvm_token" "'$next_token $@'") IFS=" " rvm_parse_break=1 ;; -v|--version) if [[ -z "$next_token" ]] ; then rvm_action="version" else rvm_ruby_version="$next_token" if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi fi ;; -n|--name) rvm_ruby_name="$next_token" if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi ;; --branch) rvm_ruby_repo_branch="$next_token" next_token="${1:-""}" shift ;; --sha) rvm_ruby_sha="$next_token" next_token="${1:-""}" shift ;; --repository|--repo|--url) rvm_ruby_repo_url="$next_token" next_token="${1:-""}" shift ;; --ree-options) if [[ -n "$next_token" ]] ; then export rvm_ree_options="${next_token//,/ }" next_token="" if [[ $# -gt 0 ]] ; then next_token="$1" ; shift fi else rvm_action="error" rvm_error_message="--ree-options *must* be followed by... well... options." fi ;; --patches|--patch) rvm_patch_names="$next_token ${rvm_patch_names:-""}" if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi rvm_patch_original_pwd="$PWD" ;; --arch|--archflags) rvm_architectures="${rvm_architectures:-},${next_token#-arch }" ; rvm_architectures="${rvm_architectures##,}" ; if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi ;; --with-arch=*) rvm_architectures="${rvm_architectures:-},${rvm_token#--with-arch=}" ; rvm_architectures="${rvm_architectures##,}" ; ;; --32) rvm_architectures="${rvm_architectures:-},i386" ; rvm_architectures="${rvm_architectures##,}" ; ;; --64) rvm_architectures="${rvm_architectures:-},x86_64" ; rvm_architectures="${rvm_architectures##,}" ; ;; --universal) rvm_architectures="${rvm_architectures:-},i386,x86_64" ; rvm_architectures="${rvm_architectures##,}" ; ;; --head) rvm_head_flag=1 ;; --static) rvm_static_flag=1 ;; --bin) if [[ "update" == "${rvm_action:-""}" ]] ; then rvm_bin_flag=1 else rvm_bin_path="$next_token" if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi fi ;; -r|--require) if [[ -z "$next_token" ]] ; then rvm_action="error" rvm_error_message="-r|--require *must* be followed by a library name." else rvm_ruby_require="$rvm_ruby_require -r$next_token" if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi fi ;; --rdoc|--yard) rvm_docs_type="$rvm_token" rvm_docs_type ;; -f|--file) rvm_action="ruby" rvm_ruby_file="$next_token" if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi ;; --passenger) rvm_log "NOTE: If you are using Passenger 3 you no longer need the passenger_ruby,\nuse the wrapper script for your ruby instead (see 'rvm wrapper')" rvm_wrapper_name="${rvm_token/--/}" ;; --editor) rvm_wrapper_name="${rvm_token/--/}" ;; --alias) if [[ -n "$next_token" ]]; then rvm_ruby_aliases="$(echo "${rvm_ruby_aliases//,/ } ${1//,/ }" | __rvm_strip)" if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi fi ;; --symlink) rvm_warn "--symlink has been removed, please see 'rvm wrapper'." if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi ;; -h|--help) rvm_action=help ;; --make) rvm_ruby_make="$next_token" if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi ;; --make-install) rvm_ruby_make_install="$next_token" ; shift if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi ;; --nice) rvm_niceness="$next_token" if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi ;; -l|--level) rvm_ruby_patch_level="p$next_token" if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi ;; --sdk) rvm_sdk="$next_token" if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi ;; --autoconf-flags) rvm_autoconf_flags="$next_token" if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi ;; --proxy) rvm_proxy="$next_token" if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi ;; -q|--quiet) rvm_quiet_flag=1 ;; -s|--silent) rvm_silent_flag=1 ;; --disable-llvm|--disable-jit) rvm_llvm_flag=0 ;; --enable-llvm|--enable-jit) rvm_llvm_flag=1 ;; --install) rvm_install_on_use_flag=1 ;; --color=*) rvm_pretty_print_flag=${rvm_token#--color=} ;; --pretty) rvm_pretty_print_flag=auto ;; --1.8|--1.9) rvm_token=${rvm_token#--} rvm_token=${rvm_token//\./} export "rvm_${rvm_token}_flag"=1 ;; --rvmrc|--versions-conf|--ruby-version) rvm_token=${rvm_token#--} rvm_token=${rvm_token//-/_} export rvm_rvmrc_flag="${rvm_token}" ;; --self|--gem|--rubygems|--reconfigure|--default|--force|--export|--summary|--latest|--yaml|--json|--archive|-shebang|--env|--path|--cron|--tail|--delete|--verbose|--import|--sticky|--create|--gems|--docs|--skip-autoreconf|--18|--19|-force-autoconf|--auto|--autoinstall-bundler|--ignore-gemsets|--skip-gemsets) rvm_token=${rvm_token#--} rvm_token=${rvm_token//-/_} export "rvm_${rvm_token}_flag"=1 ;; --dump-environment) export rvm_dump_environment_flag="$next_token" if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi ;; --clang) rvm_configure_flags="${rvm_configure_flags:-""} --with-gcc=clang" ;; -M|--make) if [[ ! -z "$next_token" ]] ; then rvm_make_flags="$rvm_make_flags ${next_token//,/ }" if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi else rvm_action="error" rvm_error_message="--make *must* be followed by make flags." fi ;; -j) if [[ ! -z "$next_token" ]] ; then rvm_make_flags="$rvm_make_flags -j$next_token" if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi else rvm_action="error" rvm_error_message="-j *must* be followed by an integer (normally the # of CPU's in your machine)." fi ;; --with-rubies) rvm_ruby_strings="$next_token" if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi ;; -C|--configure) if [[ ! -z "$next_token" ]] ; then rvm_configure_flags="${next_token//,--/ --}" if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi else rvm_action="error" rvm_error_message="--configure *must* be followed by configure flags." fi ;; --with-*|--without-*|--enable-*|--disable-*) rvm_configure_flags="${rvm_configure_flags:-""} $rvm_token" ;; -I|--include) if [[ -z "$next_token" ]] ; then rvm_action="error" rvm_error_message="-I|--include *must* be followed by a path." else rvm_ruby_load_path="$rvm_ruby_load_path:$next_token" if [[ $# -gt 0 ]] ; then next_token="$1" ; shift ; else next_token="" ; fi fi ;; --debug) export rvm_debug_flag=1 set -o verbose ;; --trace|--debug) typeset option [[ -n "${ZSH_VERSION:-""}" ]] || set -o errtrace # errexit pipefail if [[ "$rvm_token" == "--trace" ]] then export rvm_trace_flag=1 set -o xtrace [[ -n "${ZSH_VERSION:-""}" ]] || export PS4="+ \${BASH_SOURCE##\${rvm_path:-}} : \${FUNCNAME[0]:+\${FUNCNAME[0]}()} fi ;; --) if [[ "${rvm_action}" == *install ]] then rvm_configure_flags="${rvm_configure_flags:-""} $next_token else rvm_ruby_args=("$next_token" "$@") fi rvm_parse_break=1 ;; $*" *) rvm_action="error" rvm_error_message="Unrecognized command line flag: '$rvm_token'" esac ;; *) if __rvm_project_dir_check "$rvm_token" then __rvm_rvmrc_tools try_to_read_ruby "$rvm_token" else # People who are smoking crack. rvm_action="error" rvm_error_message="Unrecognized command line argument(s): '$rvm_token $@'" fi ;; esac if [[ -z "${rvm_action:-""}" && -n "${rvm_ruby_string:-""}" ]] ; then rvm_action="use" ; fi if [[ ${rvm_parse_break:-0} -eq 1 || -n "${rvm_error_message:-""}" ]] ; then break ; fi done # Empty args list. while [[ $# -gt 0 ]] ; do shift ; done if [[ -n "${rvm_error_message:-""}" ]] ; then rvm_error "$rvm_error_message ( see: 'rvm usage' )" return 1 fi } rvm() { typeset result current_result export -a rvm_ruby_args >/dev/null 2>/dev/null if (( ${rvm_ignore_rvmrc:=0} == 0 )) then : rvm_stored_umask:${rvm_stored_umask:=$(umask)} rvm_rvmrc_files=("/etc/rvmrc" "$HOME/.rvmrc") if [[ -n "${rvm_prefix:-}" ]] && ! [[ "$HOME/.rvmrc" -ef "${rvm_prefix}/.rvmrc" ]] then rvm_rvmrc_files+=( "${rvm_prefix}/.rvmrc" ) fi \${LINENO} > " for rvmrc in "${rvm_rvmrc_files[@]}" do if [[ -f "$rvmrc" ]] then if GREP_OPTIONS="" \grep '^\s*rvm .*$' "$rvmrc" >/dev/null 2>&1 then printf "%b" " Error: $rvmrc is for rvm settings only. rvm CLI may NOT be called from within $rvmrc. Skipping the loading of $rvmrc" return 1 else source "$rvmrc" fi fi done unset rvm_rvmrc_files fi disk_version="$(cat "$rvm_path/VERSION") ($(cat "$rvm_path/RELEASE" 2>/dev/null))" if [[ -s "$rvm_path/VERSION" && "${rvm_version:-}" != "${disk_version:-}" && "reload" != "${1:-}" ]] then if [[ ${rvm_auto_reload_flag:-0} -gt 0 ]] then __rvm_project_rvmrc_lock=0 rvm_reload_flag=1 source "${rvm_scripts_path:-${rvm_path}/scripts}/rvm" else printf "%b" " A RVM version ${disk_version} is installed yet ${rvm_version} is loaded. Please do one of the following: * 'rvm reload' * open a new shell * 'echo rvm_auto_reload_flag=1 >> ~/.rvmrc' # for auto reload with msg. * 'echo rvm_auto_reload_flag=2 >> ~/.rvmrc' # for silent auto reload. " return 1 fi fi __rvm_initialize __rvm_setup next_token="$1" [[ $# -eq 0 ]] || shift __rvm_parse_args "$@" result=$? rvm_action="${rvm_action:-usage}" [[ $result -gt 0 ]] || case "$rvm_action" in use) if rvm_is_a_shell_function then __rvm_use fi ;; srcdir) __rvm_source_dir ;; strings) __rvm_strings ;; version) __rvm_version ;; ls|list) "$rvm_scripts_path/list" "${rvm_ruby_args[@]}" ;; # TODO: Make debug run in the current environment, issues with not exported vars. debug) rvm_is_not_a_shell_function="${rvm_is_not_a_shell_function}" "$rvm_scripts_path/info" '' debug ;; usage) __rvm_usage ;; benchmark) source "$rvm_scripts_path/functions/benchmark" __rvm_benchmark ;; inspect) __rvm_inspect ;; update) printf "%b" "ERROR: rvm update has been removed. See 'rvm get' and rvm 'rubygems' CLI API instead\n" ;; reset) source "$rvm_scripts_path/functions/reset" __rvm_reset ;; reboot) source "$rvm_scripts_path/functions/cleanup" __rvm_reboot ;; implode|seppuku) source "$rvm_scripts_path/functions/implode" __rvm_implode ;; get) next_token="${1:-}" (( $# > 0 )) && shift [[ "$next_token" == "${rvm_action}" ]] && shift tmpdir="${TMPDIR:-/tmp}" \cp -f "$rvm_scripts_path/get" "$tmpdir/$$" if bash "$tmpdir/$$" "${rvm_ruby_args[@]}" then rvm_reload_flag=1 else rvm_error "Could not update RVM, get some help at #rvm IRC channel at freenode servers." fi \rm -f $tmpdir/$$ ;; help|rtfm|env|current|list|monitor|notes|package|extract|pkg|requirements) if (( $# > 0 )) then next_token="$1" shift else next_token="" fi if [[ "$next_token" == "${rvm_action}" ]] then shift fi "$rvm_scripts_path/${rvm_action}" "${rvm_ruby_args[@]}" ;; info) rvm_is_not_a_shell_function="${rvm_is_not_a_shell_function}" "$rvm_scripts_path/${rvm_action}" "${rvm_ruby_args[@]}" ;; cleanup|tools|snapshot|disk-usage|repair|alias|docs|rubygems|migrate|upgrade|cron) __rvm_run_script "$rvm_action" "${rvm_ruby_args[@]}" ;; wrapper) "$rvm_scripts_path/wrapper" "$rvm_ruby_string" "$rvm_wrapper_name" "${rvm_ruby_args[@]}" result=$? unset rvm_wrapper_name ;; do) old_rvm_ruby_string=${rvm_ruby_string:-} unset rvm_ruby_string export rvm_ruby_strings ( if [[ -n "${rvm_in_flag}" && -d "${rvm_in_flag}" ]] then builtin cd "${rvm_in_flag}" fi "$rvm_scripts_path/set" "$rvm_action" "${rvm_ruby_args[@]}" ) result=$? # Restore the state pre-sets. [[ -n "$old_rvm_ruby_string" ]] && rvm_ruby_string=$old_rvm_ruby_string unset old_rvm_ruby_string ;; rvmrc) __rvm_rvmrc_tools "${rvm_ruby_args[@]}" ;; gemset) if [[ ${rvm_use_flag:-0} -eq 1 ]] then __rvm_gemset_use else export rvm_ruby_strings "$rvm_scripts_path/gemsets" "${rvm_ruby_args[@]}" ; result=$? rvm_ruby_strings="" # Clear the gemset. if [[ ${rvm_delete_flag:-0} -eq 1 ]] ; then gem_prefix="$(echo "${GEM_HOME:-""}" | \sed 's/'${rvm_gemset_separator:-"@"}'.*$//')" if [[ "${GEM_HOME:-""}" == "${gem_prefix}${rvm_gemset_separator:-"@"}${rvm_gemset_name}" ]] ; then rvm_ruby_gem_home="$gem_prefix" GEM_HOME="$rvm_ruby_gem_home" GEM_PATH="$rvm_ruby_gem_home:$rvm_ruby_gem_home${rvm_gemset_separator:-"@"}global" export rvm_ruby_gem_home GEM_HOME GEM_PATH fi unset gem_prefix fi fi ;; reload) rvm_reload_flag=1 ;; tests|specs) rvm_action="rake" ; __rvm_do ;; remove) export rvm_path if [[ -n "${rvm_ruby_strings}" ]] then "$rvm_scripts_path"/manage "$rvm_action" "${rvm_ruby_strings//*-- }" else "$rvm_scripts_path"/manage "$rvm_action" fi rvm_ruby_string=default __rvm_use ;; fetch|uninstall|reinstall) export rvm_path if [[ -n "${rvm_ruby_strings}" ]] then "$rvm_scripts_path"/manage "$rvm_action" "${rvm_ruby_strings//*-- }" else "$rvm_scripts_path"/manage "$rvm_action" fi ;; try_install|install) export rvm_path if [[ -n "${rvm_ruby_strings}" ]] then typeset save_ruby selected_ruby="$( __rvm_select && echo $rvm_env_string )" if [[ -z "${selected_ruby}" ]] then rvm_error "Could not detect ruby version/name for installation, please be more specific." false #report error elif (( ${rvm_force_flag:-0} == 0 )) && "$rvm_scripts_path"/list strings | GREP_OPTIONS="" \grep "^${selected_ruby}$" > /dev/null then rvm_log "Already installed ${selected_ruby}. To reinstall use: rvm reinstall ${rvm_ruby_strings} " else if [[ $(ls -1 $rvm_rubies_path/*/bin/ruby 2>/dev/null | wc -l) -eq 0 ]] && [[ ${rvm_is_not_a_shell_function:-0} -eq 0 ]] then { echo "Ruby (and needed base gems) for your selection will be installed shortly." echo "Before it happens, please read and execute the instructions below." echo "Please use a separate terminal to execute any additional commands." "$rvm_scripts_path"/requirements echo "Press 'q' to continue." } | less fi "$rvm_scripts_path"/manage install "${rvm_ruby_strings}" fi else rvm_error "Can not use or install 'all' rubies." false #report error fi ;; mount|automount) "${rvm_scripts_path}/external" "$rvm_action" "${rvm_ruby_args[@]}" ;; export) __rvm_export "$rvm_export_args" ;; unexport) __rvm_unset_exports ;; error) false ;; answer) source "$rvm_scripts_path/functions/fun" __rvm_Answer_to_the_Ultimate_Question_of_Life_the_Universe_and_Everything ; result=42 ;; question) source "$rvm_scripts_path/functions/fun" __rvm_ultimate_question ; result=42 ;; *) if [[ -n "${rvm_action:-""}" ]] ; then rvm_error "unknown action '$rvm_action'" else __rvm_usage fi false # result esac current_result=$? # Use the result of first found error (( result > 0 )) || result=${current_result} [[ $result -gt 0 ]] || case "$rvm_action" in reinstall|try_install|install) if [[ $(ls -1 $rvm_rubies_path/*/bin/ruby 2>/dev/null | wc -l) -eq 1 ]] && [[ ! -f "${rvm_environments_path}/default" ]] then if rvm_is_a_shell_function then rvm_default_flag=1 __rvm_use fi fi ;; esac current_result=$? # Use the result of first found error (( result > 0 )) || result=${current_result} if [[ ${rvm_reload_flag:-0} -eq 1 ]] then __rvm_project_rvmrc_lock=0 source "$rvm_scripts_path/rvm" fi typeset __local_rvm_trace_flag __local_rvm_trace_flag=${rvm_trace_flag:-0} __rvm_teardown if (( __local_rvm_trace_flag > 0 )) then set +o verbose set +o xtrace [[ -n "${ZSH_VERSION:-""}" ]] || set +o errtrace fi return ${result:-0} } 1.18.54. patchsets #!/usr/bin/env bash rvm_base_except="selector" source "$rvm_scripts_path/base" source "$rvm_scripts_path/patches" lookup_patchset() { typeset paths lookup_path if [[ -z "$1" ]] then echo "Usage: rvm patchset show name" return 1 fi paths=($(__rvm_ruby_string_paths_under "$rvm_path/patchsets" | sort -r)) for lookup_path in "${paths[@]}" do if [[ -s "$lookup_path/$1" ]] then cat "$lookup_path/$1" return 0 fi done return 1 } # Return the full patch for a given patch. __rvm_lookup_full_patch_path() { typeset directory directories extension patch_path directories=($(__rvm_patch_lookup_path)) # Absolute path, pwd and then finally the rvm patches path. for directory in "${directories[@]}" ; do for extension in {"",.patch,.diff}; do patch_path="${directory}${1}${extension}" if [[ -s "$patch_path" ]]; then echo "$patch_path" return fi done done return 1 } usage() { printf "%b" " Usage: rvm patchset {show,lookup} [patchset] Description: Tools for manipulating patchsets. " return 1 } args=($*) action="${args[0]}" patchset="${args[1]}" args="$(echo ${args[@]:2})" # Strip trailing / leading / extra spacing. case "$action" in show|lookup) lookup_patchset "$patchset" ;; *) usage ;; esac exit $? 1.18.55. base #!/usr/bin/env bash # Base is a collection of general files + commonly included setup functions. : rvm_trace_flag:${rvm_trace_flag:=0} if (( rvm_trace_flag > 0 )) then set -o xtrace # set -o errexit if [[ -z "${ZSH_VERSION:-}" ]] then # set -o errtrace # set -o pipefail export PS4 PS4="+ \${BASH_SOURCE##\${rvm_path:-}} : \${FUNCNAME[0]:+\${FUNCNAME[0]}()} \${LINENO} > " fi elif [[ ${rvm_debug_flag:-0} > 0 ]] then rvm_debug_flag=0 fi export __array_start rvm_path >/dev/null # # Setup environment parameters. # if [[ -n "${ZSH_VERSION:-}" ]] then __array_start=1 else __array_start=0 fi if (( ${rvm_ignore_rvmrc:=0} == 0 )) then : rvm_stored_umask:${rvm_stored_umask:=$(umask)} rvm_rvmrc_files=("/etc/rvmrc" "$HOME/.rvmrc") if [[ -n "${rvm_prefix:-}" ]] && ! [[ "$HOME/.rvmrc" -ef "${rvm_prefix}/.rvmrc" ]] then rvm_rvmrc_files+=( "${rvm_prefix}/.rvmrc" ) fi for rvmrc in "${rvm_rvmrc_files[@]}" do if [[ -f "$rvmrc" ]] then if GREP_OPTIONS="" \grep '^\s*rvm .*$' "$rvmrc" >/dev/null 2>&1 then printf "%b" " Error: $rvmrc is for rvm settings only. rvm CLI may NOT be called from within $rvmrc. Skipping the loading of $rvmrc" return 1 else source "$rvmrc" fi fi done unset rvm_rvmrc_files fi export rvm_path if [[ -z "${rvm_path:-}" ]] then if (( UID == 0 )) && [[ -d "/usr/local/rvm" ]] then rvm_path="/usr/local/rvm" elif [[ -d "${HOME}/.rvm" ]] then rvm_path="${HOME}/.rvm" elif [[ -d "/usr/local/rvm" ]] then rvm_path="/usr/local/rvm" else echo "Can't find rvm install!" 1>&2 ; exit 1 fi fi true ${rvm_scripts_path:="$rvm_path/scripts"} # Initialize all main RVM variables. source "$rvm_scripts_path/initialize" # Load the general scripts. # Use rvm_base_except="selector", for example, to override the loading. case " ${rvm_base_except:-} " in (*[[:space:]]selector[[:space:]]*) true # do not load. ;; (*) source "$rvm_scripts_path/selector" source "$rvm_scripts_path/selector_gemsets" ;; esac typeset -a scripts scripts=( logging utility init cleanup env rvmrc install environment gemset db bundler ) for entry in ${scripts[@]} ; do source "$rvm_scripts_path/functions/$entry" done unset scripts entry rvm_base_except 1.18.56. gemsets #!/usr/bin/env bash source "$rvm_scripts_path/base" source "$rvm_scripts_path/functions/build" # For gems with C extensions. rvm_ruby_gem_home="${rvm_ruby_gem_home:-$GEM_HOME}" if [[ ! -d "$rvm_ruby_gem_home" ]] && builtin command -v gem > /dev/null 2>&1 then rvm_ruby_gem_home="$(gem env home)" fi usage() { cat -v "${rvm_help_path}/gemset" } gemset_list_all() { for rvm_ruby_string in $( rvm_project_rvmrc=0 rvm list strings ) do (__rvm_use ; gemset_list) done unset rvm_ruby_string } gemset_list_strings() { typeset gem_string for rvm_ruby_string in $( rvm_project_rvmrc=0 rvm list strings ) do for gem_string in "${rvm_gems_path:-${rvm_path}/gems}/${rvm_ruby_string}${rvm_gemset_separator:-@}"* do printf "%b" "${gem_string##*/}\n" done done unset rvm_ruby_string } gemset_update() { if [[ -z "$rvm_ruby_strings" ]] then rvm_log "Running gem update for all rubies and gemsets." rvm_ruby_strings="$( builtin cd "${rvm_gems_path:-"$rvm_path/gems"}" ; find . -maxdepth 1 -mindepth 1 -type d -print 2>/dev/null \ | GREP_OPTIONS="" \grep -v '^\(doc\|cache\|@\|system\)' | \tr '\n' ',' )" rvm_ruby_strings="${rvm_ruby_strings/%,}" rvm_ruby_strings="${rvm_ruby_strings//.\/}" else rvm_log "Running gem update for the specified rubies." fi export rvm_ruby_strings "$rvm_scripts_path/set" "gem" "update" return $? } gemset_globalcache() { typeset gc_status globalcache_enabled directories directory_name \ full_directory_path directory_name if [[ "$1" == "enabled" ]] then if __rvm_using_gemset_globalcache then gc_status="Enabled" globalcache_enabled=0 else gc_status="Disabled" globalcache_enabled=1 fi rvm_log "Gemset global cache is currently: $gc_status" return $globalcache_enabled elif [[ "$1" == "disable" ]] then rvm_log "Removing the global cache (note: this will empty the caches)" directories=($( builtin cd "${rvm_gems_path:-"$rvm_path/gems"}" ; find . -maxdepth 1 -mindepth 1 -type d -print) ) for directory_name in "${directories[@]//.\/}" do current_cache_path="${rvm_gems_path:-"$rvm_path/gems"}/$directory_name/cache" if [[ -L "$current_cache_path" \ && "$(readlink "$current_cache_path")" == "$rvm_gems_cache_path" ]] then rvm_log "Reverting the gem cache for $directory_name to an empty directory." rm -f "$current_cache_path" 2>/dev/null mkdir -p "$current_cache_path" 2>/dev/null fi done "$rvm_scripts_path/db" "$rvm_user_path/db" "use_gemset_globalcache" "delete" elif [[ "$1" == "enable" ]] then rvm_log "Enabling global cache for gems." mkdir -p "$rvm_gems_cache_path" directories=($( builtin cd "${rvm_gems_path:-"$rvm_path/gems"}" ; find . -maxdepth 1 -mindepth 1 -type d -print) ) for directory_name in "${directories[@]//.\/}" do current_cache_path="${rvm_gems_path:-"$rvm_path/gems"}/$directory_name/cache" if [[ -d "$current_cache_path" && ! -L "$current_cache_path" ]] then rvm_log "Moving the gem cache for $directory_name to the global cache." mv "$current_cache_path/"*.gem "$rvm_gems_cache_path/" 2>/dev/null case "${current_cache_path%\/}" in *cache) __rvm_rm_rf "$current_cache_path" ln -fs "$rvm_gems_cache_path" "$current_cache_path" ;; esac fi done "$rvm_scripts_path/db" "$rvm_user_path/db" "use_gemset_globalcache" "true" else printf "%b" " Usage: rvm gemset globalcache {enable,disable,enabled} Enable / Disable / Status the use of a global gem cachedir. " return 1 fi } gemset_name() { echo "${rvm_ruby_gem_home##*${rvm_gemset_separator:-"@"}}" return $? } gemset_dir() { echo "$rvm_ruby_gem_home" return $? } gemset_create() { typeset gem_home gemset gemsets prefix if [[ -n "$rvm_ruby_string" ]] then __rvm_select fi prefix=$(echo $rvm_ruby_gem_home | sed 's/'${rvm_gemset_separator:-"@"}'.*$//') gemsets=(${args[@]}) for gemset in "${gemsets[@]}" do if [[ "$(__rvm_env_string)" == "system" ]] then rvm_error "Can not create gemset before using a ruby. Try 'rvm use <some ruby>'." return 1 fi if [[ "$gemset" == *"${rvm_gemset_separator:-"@"}"* ]] then rvm_error "Can not create gemset '$gemset', it contains a \"${rvm_gemset_separator:-"@"}\"." return 2 fi if [[ -z "$gemset" || "$gemset" == *"${rvm_gemset_separator:-"@"}" ]] then rvm_error "Can not create gemset '$gemset', Missing name. " return 3 fi gem_home="${prefix}${rvm_gemset_separator:-"@"}${gemset}" [[ -d "$gem_home/bin" ]] || mkdir -p "$gem_home/bin" : rvm_gems_cache_path:${rvm_gems_cache_path:=${rvm_gems_path:-"$rvm_path/gems"}/cache} # When the globalcache is enabled, we need to ensure we setup the cache directory correctly. if __rvm_using_gemset_globalcache then if [[ -d "$gem_home/cache" && ! -L "$gem_home/cache" ]] then mv "$gem_home/cache"/*.gem "$rvm_gems_cache_path/" 2>/dev/null __rvm_rm_rf "$gem_home/cache" fi ln -fs "$rvm_gems_cache_path" "$gem_home/cache" fi if ! ( rvm_ruby_string="$(__rvm_env_string)${rvm_gemset_separator:-"@"}${gemset}" __rvm_use ) then rvm_error "Can not create environment file for '$gemset', Could not use ruby. " return 4 fi rvm_log "'$gemset' gemset created ($gem_home)." done return 0 } __gemset_list_single() { typeset gemset current_gemset gemset="$1" current_gemset="$2" gemset="${gemset##*${rvm_gemset_separator:-@}}" [[ -n "${gemset}" ]] || gemset="(default)" [[ -n "${current_gemset}" ]] || current_gemset="(default)" if [[ "${gemset}" == "${current_gemset}" ]] then if [[ "${args[0]:-""}" != "strings" ]] then echo "=> ${gemset}" else echo "${gemset} (current)" fi else if [[ "${args[0]:-""}" != "strings" ]] then echo " ${gemset}" else echo "$gemset" fi fi } gemset_list() { if [[ ${rvm_ruby_selected_flag:-0} -eq 0 ]] then __rvm_select fi [[ -d "${rvm_gems_path:-"$rvm_path/gems"}" ]] || { rvm_error "${rvm_gems_path:-"$rvm_path/gems"} does not exist!" return 1 } [[ -n "${rvm_ruby_string:-""}" ]] || { rvm_error "\$rvm_ruby_string is not set!" return 1 } typeset current_gemset IFS current_gemset=$(__rvm_current_gemset) IFS="" [[ "${args[0]:-""}" == "strings" ]] || rvm_log "\ngemsets for $rvm_ruby_string (found in ${rvm_gems_path:-"$rvm_path/gems"}/$rvm_ruby_string)" for gemset in ${rvm_gems_path:-${rvm_path}/gems}/${rvm_ruby_string}${rvm_gemset_separator:-@}* do __gemset_list_single "${gemset}" "${current_gemset}" done [[ "${args[0]:-""}" == "strings" ]] || printf "%b" "\n" return 0 } gemset_after_delete_cleanup() { typeset rvm_gemset_name ruby_at_gemset gemdir rvm_gemset_name=$1 ruby_at_gemset=$2 gemdir=$3 if [[ -L "$gemdir/cache" ]] then rm -f "$gemdir/cache" fi ( for item in $( $rvm_scripts_path/alias search_by_target ${ruby_at_gemset} ) do $rvm_scripts_path/alias delete ${item} done find "${rvm_bin_path:=$rvm_path/bin}" \( -name \*${ruby_at_gemset} -or -lname \*${ruby_at_gemset}/\* \) -delete ) rm -rf "${rvm_wrappers_path:="$rvm_path/wrappers"}/${ruby_at_gemset}" } gemset_delete() { gemsets=(${args[@]}) if (( ${rvm_ruby_selected_flag:-0} == 0)) then __rvm_select fi if [[ -n "${gemsets[$__array_start]}" ]] then rvm_gemset_name="${gemsets[$__array_start]}" fi if [[ -n "$rvm_gemset_name" ]] then ruby_at_gemset="$rvm_ruby_string${rvm_gemset_separator:-"@"}$rvm_gemset_name" gemdir="${rvm_gems_path:-"$rvm_path/gems"}/${ruby_at_gemset}" if [[ -d "$gemdir" && "$gemdir" != '/' && ${rvm_force_flag:-0} -gt 0 ]] then __rvm_rm_rf "$gemdir" gemset_after_delete_cleanup $rvm_gemset_name $ruby_at_gemset $gemdir elif [[ -d "$gemdir" ]] then rvm_warn "Are you SURE you wish to remove the entire gemset directory '$rvm_gemset_name' ($gemdir)?" printf "%b" "(anything other than 'yes' will cancel) > " read response if [[ "yes" == "$response" ]] then __rvm_rm_rf "$gemdir" gemset_after_delete_cleanup $rvm_gemset_name $ruby_at_gemset $gemdir else rvm_log "Not doing anything, phew... close call that one eh?" return 2 fi else rvm_log "$gemdir did not previously exist. Ignoring." fi else rvm_error "A gemset name must be specified in order to delete a gemset." return 1 fi return 0 } gemset_empty() { typeset gemdir entry gemsets=(${args[@]}) if [[ -z "${rvm_ruby_gem_home:-""}" ]] then __rvm_select fi if [[ -n "${gemsets[$__array_start]}" ]] then rvm_gemset_name="${gemsets[$__array_start]}" rvm_gemset_name="${rvm_gemset_name#default}" ruby_at_gemset="$rvm_ruby_string${rvm_gemset_name:+${rvm_gemset_separator:-"@"}}${rvm_gemset_name}" gemdir="${rvm_gems_path:-"$rvm_path/gems"}/${ruby_at_gemset}" else gemdir="${rvm_ruby_gem_home}" fi if [[ ${rvm_force_flag:-0} -gt 0 ]] then for entry in "$gemdir"/bin/* "$gemdir"/doc/* "$gemdir"/gems/* "$gemdir"/specifications/* do __rvm_rm_rf "$entry" done elif [[ -d "$gemdir" ]] then rvm_warn "Are you SURE you wish to remove the installed gems for gemset '$(basename "$gemdir")' ($gemdir)?" echo -n "(anything other than 'yes' will cancel) > " read response if [[ "yes" == "$response" ]] then for entry in "$gemdir"/bin/* "$gemdir"/doc/* "$gemdir"/gems/* "$gemdir"/specifications/* ; do __rvm_rm_rf "$entry" done else rvm_log "Not doing anything, phew... close call that one eh?" fi else rvm_log "$gemdir did not previously exist. Ignoring." fi return 0 } # Migrate gemsets from ruby X to ruby Y gemset_copy() { typeset source_ruby destination_ruby source_path destination_path # Clear the current environment so that it does not influence this operation. unset rvm_gemset_name rvm_ruby_gem_home GEM_HOME GEM_PATH source_ruby="${args[$__array_start]:-""}" args[$__array_start]="" ; args=(${args[@]}) destination_ruby="${args[$__array_start]:-""}" args[$__array_start]="" ; args=(${args[@]}) if [[ -z "$destination_ruby" || -z "$source_ruby" ]] then rvm_error "Source and destination must be specified: 'rvm gemset copy X Y'" return 1 fi # Verify the destination gemset exists before attempting to use it. ( rvm_ruby_string="$destination_ruby" export rvm_create_flag=1 { __rvm_ruby_string && __rvm_gemset_select; } 2> /dev/null ) result=$? if [[ $result -ne 0 ]] then rvm_error "Destination gemset '$destination_ruby' does not yet exist." return 1 fi # TODO: Account for more possibilities: # rvm gemset copy 1.9.2 @gemsetb # rvm gemset copy @gemseta @gemsetb # rvm gemset copy gemseta gemsetb # rvm gemset copy gemseta 1.8.7@gemsetb # # # # From 1.9.2 default to current ruby, 1.9.2 exists. Current ruby, gemseta exists. Currenty Ruby, gemseta exists. Currenty Ruby@gemseta, current ruby@gemseta exists. source_path=$( rvm_ruby_string="$source_ruby" { __rvm_ruby_string && __rvm_gemset_select; } > /dev/null 2>&1 echo $rvm_ruby_gem_home ) destination_path=$( rvm_ruby_string="$destination_ruby" { __rvm_ruby_string && __rvm_gemset_select; } echo $rvm_ruby_gem_home ) > /dev/null 2>&1 if [[ -z "$source_path" || ! -d "$source_path" ]] then rvm_error "Unable to expand '$source_ruby' or directory does not exist." return 1 fi if [[ -z "$destination_path" ]] then rvm_error "Unable to expand '$destination_ruby'." return 1 fi if [[ -d "$source_path" ]] then rvm_log "Copying gemset from $source_ruby to $destination_ruby" for dir in bin doc gems specifications cache bundle do mkdir -p "$destination_path/$dir" if [[ -d "$source_path/$dir" ]] then cp -Rf "$source_path/$dir" "$destination_path/" elif [[ -L "$source_path/$dir" ]] then cp "$source_path/$dir" "$destination_path/$dir" fi done rvm_log "Making gemset for $destination_ruby pristine." __rvm_run_with_env "gemset.pristine" "$destination_ruby" "rvm gemset pristine" else rvm_error "Gems directory does not exist for $source_path ($source_path)" return 1 fi } # Migrate gemsets from ruby X to ruby Y gemset_rename() { typeset source_name destination_name source_path destination_path source_name="${args[$__array_start]:-""}" args[$__array_start]="" ; args=(${args[@]}) destination_name="${args[$__array_start]:-""}" args[$__array_start]="" ; args=(${args[@]}) if [[ -z "$destination_name" || -z "$source_name" ]] then rvm_error "Source and destination gemsets must be specified: 'rvm gemset rename X Y'" return 1 fi source_path="$(rvm_silence_logging=1 rvm_gemset_name=${source_name} __rvm_use "${rvm_ruby_string}@${source_name}" ; gem env gemdir)" if [[ -z "$source_path" || ! -d "$source_path" ]] then rvm_error "gemset '$source_name' does not exist." return 1 fi destination_path=${source_path/%$source_name/$destination_name} if [[ -d "$source_path" ]] then if [[ ! -d "$destination_path" ]] then mv "$source_path" "$destination_path" else rvm_error "Gemset $destination_name already exists!" return 1 fi else rvm_error "Gems directory does not exist for $source_path ($source_path)" return 1 fi } gemset_unpack() { typeset gems name directory version _platforms directory="${args[$__array_start]}" if [[ -z "$directory" ]] then directory="vendor/gems" fi if [[ -n "$rvm_ruby_gem_home" ]] then export GEM_HOME="$rvm_ruby_gem_home" export GEM_PATH="$rvm_ruby_gem_home:$rvm_ruby_global_gems_path" fi rvm_log "Unpacking current environments gemset to ${directory}\n" unset -f gem while read gem_name version _platforms do ( command gem unpack "$gem_name" -v"$version" --target "$directory" )& done < <( GEM_PATH="$GEM_HOME" __rvm_list_gems ) wait rvm_log "Unpacking into ${directory} complete\n" return 0 } gemset_export() { typeset gem_name version versions _platforms rvm_file_name="${rvm_file_name:-${gems_args// }}" if [[ -n "$rvm_ruby_gem_home" ]] then export GEM_HOME="$rvm_ruby_gem_home" export GEM_PATH="$rvm_ruby_gem_home:$rvm_ruby_global_gems_path" fi if [[ -n "$rvm_file_name" ]] then [[ "${rvm_file_name}" =~ Gemfile ]] || rvm_file_name="${rvm_file_name%.gems}.gems" else if [[ -n "$rvm_gemset_name" ]] then rvm_file_name="$rvm_gemset_name.gems" else rvm_file_name="default.gems" fi fi rvm_log "Exporting current environments gemset to $rvm_file_name" if [[ -f "$rvm_file_name" ]] then rm -f "$rvm_file_name" fi if [[ "${rvm_file_name}" =~ Gemfile ]] then printf "%b" "source :rubygems #ruby=${GEM_HOME##*/} " else printf "%b" "# $rvm_file_name generated gem export file. \ Note that any env variable settings will be missing. \ Append these after using a ';' field separator " fi > "$rvm_file_name" if (( ${rvm_latest_flag:-0} == 0 )) then while read gem_name version _platforms do if [[ "${rvm_file_name}" =~ Gemfile ]] then echo "gem '$gem_name', '$version'" else echo "$gem_name -v$version" fi done < <( GEM_PATH="$GEM_HOME" __rvm_list_gems ) else while read gem_name versions do if [[ "${rvm_file_name}" =~ Gemfile ]] then echo "gem '$gem_name'" else echo "$gem_name" fi done < <( GEM_PATH="$GEM_HOME" gem list ) fi >> "$rvm_file_name" return 0 } gemset_import() { unset -f gem if [[ -n "${rvm_ruby_gem_home:-""}" ]] then export GEM_HOME="$rvm_ruby_gem_home" export GEM_PATH="$rvm_ruby_gem_home" else rvm_ruby_gem_home=${GEM_HOME:-$(gem env gemdir)} fi #rvm_gemset_name="${gems_args//.gem*/}" #rvm_gemset_name="${gems_args// /}" rvm_file_name="${gems_args// /}" # TODO: this could likely be better with find if [[ -s "${rvm_file_name%.gems*}.gems" ]] then rvm_file_name="${rvm_file_name%.gems*}.gems" elif [[ -s "${rvm_gemset_name}.gems" ]] then rvm_file_name="${rvm_gemset_name}.gems" elif [[ -s "default.gems" ]] then rvm_file_name="default.gems" elif [[ -s "system.gems" ]] then rvm_file_name="system.gems" elif [[ -s ".gems" ]] then rvm_file_name=".gems" else rvm_error "No *.gems file found." return 1 fi if [[ ! -d "$rvm_ruby_gem_home/specifications/" ]] then mkdir -p "$rvm_ruby_gem_home/specifications/" fi if [[ ! -d "$rvm_gems_cache_path" ]] then mkdir -p "$rvm_gems_cache_path" # Ensure the base cache dir is initialized. fi if [[ -s "$rvm_file_name" ]] then printf "%b" "\nInstalling gems listed in $rvm_file_name file...\n\n" rvm_ruby_gem_list=$( builtin cd "$rvm_ruby_gem_home/specifications/" ; find . -maxdepth 1 -mindepth 1 -type f -print 2> /dev/null | \ sed -e 's#.gems.*$##' -e 's#^./##g' 2> /dev/null ) # rvm_ruby_gem_list="${rvm_ruby_gem_list//.\/}" # Read the file into an array by changing the IFS temporarily. typeset oldifs oldifs="${IFS}" # Yes, that's a newline....edit with care. IFS=" " typeset -a lines lines=( $(cat "${rvm_file_name}") ) IFS="${oldifs}" # Parse the lines, throwing out comments and empty lines. for line in "${lines[@]}" do if [[ "${line}" != '#'* && -n "${line// /}" ]] then gems_args="$line" gem_install fi done printf "%b" "\nProcessing of $rvm_file_name is complete.\n\n" else rvm_error "${rvm_file_name} does not exist to import from." fi } __rvm_parse_gems_args() { gem="${gems_args/;*}" gem_prefix="" if echo "$gems_args" | GREP_OPTIONS="" \grep ';' >/dev/null 2>&1 then gem_prefix="${gems_args/*;}" fi if match "$gem" "*.gem$" then gem_name="$(basename "${gem/.gem/}" | awk -F'-' '{$NF=NULL;print}')" gem_version="$(basename "${gem/.gem/}" | awk -F'-' '{print $NF}' )" gem_postfix="$(basename "${gem/*.gem/}")" else gem_name="${gem/ */}" case "$gem" in *--version*) gem_version=$( echo "$gem" | sed -e 's#.*--version[=]*[ ]*##' | awk '{print $1}' ) gem_postfix="$( echo "$gem" | sed -e "s#${gem_name/ /}##" -e "s#--version[=]*[ ]*${gem_version/ /}##" )" ;; *-v*) gem_version=$( echo "$gem" | sed -e 's#.*-v[=]*[ ]*##' | awk '{print $1}' ) gem_postfix="$( echo "$gem" | sed -e "s#${gem_name/ /}##" -e "s#-v[=]*[ ]*${gem_version/ /}##" )" #" ;; *) unset gem_version # no version ;; esac fi if [[ -s "$gem" ]] ; then gem_file_name="$gem" elif match "$gem" "*.gem" then gem_file_name="$gem" elif [[ -z "${gem_version/ /}" ]] then gem_file_name="${gem_name/ /}*.gem" else # version gem_file_name="${gem_name/ /}-${gem_version/ /}.gem" fi } # Install a gem gem_install() { typeset gem gem_prefix gem_name gem_version gem_file_name gem_postfix cache_file gem_file_name gem_string gem_action _command result=0 # First we parse the gem args to pick apart the pieces. __rvm_parse_gems_args # Now we determine if a .gem cache file is already installed if (( ${rvm_force_flag:-0} == 0 )) && [[ -f "${rvm_ruby_gem_home}/specifications/$(basename "$gem_file_name")spec" ]] then gem="" rvm_log "$gem_name $gem_version is already installed." else if [[ -s "$gem" ]] then cache_file="$gem" elif [[ -s "$(__rvm_current_gemcache_dir)/${gem_file_name}" ]] then cache_file="$(__rvm_current_gemcache_dir)/${gem_file_name}" else true ${cache_file:=$( find "$(__rvm_current_gemcache_dir)/${gem_file_name}" -maxdepth 1 -mindepth 1 -type f -print 2> /dev/null | sort | head -n1)} cache_file="${cache_file/.\/}" fi if [[ ! -s "$cache_file" ]] then if [[ -s "$gem_file_name" ]] then gem="$gem_file_name" elif [[ -z "${gem_version// /}" ]] then gem="${gem_name// /}" else gem="${gem_name// /} -v $gem_version" fi else # cached gem_file_name="$(basename "$cache_file")" gem_string="$(echo "$gem_file_name" | sed 's#\.gem$##')" if (( ${rvm_force_flag:-0} == 0 )) && [[ -s "${rvm_ruby_gem_home}/specifications/$(basename $gem_file_name)spec" ]] then unset gem # already installed, not forcing reinstall. rvm_log "$gem_name $gem_version exists, skipping (--force to re-install)" else if [[ -s "$(__rvm_current_gemcache_dir)/$(basename $gem_file_name)" ]] then mkdir -p "${rvm_tmp_path}/$$/" mv "$(__rvm_current_gemcache_dir)/$gem_file_name" "${rvm_tmp_path}/$$/$gem_file_name" gem="${rvm_tmp_path}/$$/$gem_file_name -f -l" else gem="$cache_file" fi fi fi fi # If $gem is still set, go forward with the install. if [[ -n "$gem" ]] then # TODO: Set vars if fourth field is non-empty (means that there are conditional statements to execute in the gem install line. if [[ -n "$rvm_ruby_gem_home" && "$rvm_ruby_gem_home" != "${rvm_gems_path:-"$rvm_path/gems"}" ]] then _command="GEM_HOME='$rvm_ruby_gem_home' GEM_PATH='$rvm_ruby_gem_home' $gem_prefix gem install --remote $gems_args $rvm_gem_options $gem_postfix $vars" else _command="$gem_prefix gem install --ignore-dependencies --remote $gems_args $rvm_gem_options -q $gem $gem_postfix $vars" fi unset -f gem __rvm_run "gem.install" "$_command" "installing ${gem_name} ${gem_version}..." result=$? if (( result == 0 )) then rvm_log "$gem_name $gem_version installed." else rvm_log "$gem_name $gem_version failed to install ( output logged to: $rvm_log_path/$rvm_ruby_string/gem.install.log )" fi fi return $result } # Output the user's current gem directory. gemset_info() { if (( ${rvm_user_flag:-0} == 1 )) then (__rvm_use system ; gem env | GREP_OPTIONS="" \grep "\- $HOME" | awk '{print $NF}') elif [[ ${rvm_system_flag:-0} == 1 ]] then (__rvm_use system ; gem env $action system) # elif [[ -n "${rvm_ruby_string:-""}${rvm_gemset_name:+${rvm_gemset_separator:-"@"}}${rvm_gemset_name:-}" ]] # then # (__rvm_use "${rvm_ruby_string:-""}${rvm_gemset_name:+${rvm_gemset_separator:-"@"}}${rvm_gemset_name:-}" ; gem env $action) # elif [[ -n "${GEM_HOME:-""}" ]] # then # echo "$GEM_HOME" else gem env $action fi return $? } gemset_prune() { typeset temporary_cache_path live_cache_path gemset_name version versions \ cached_gem_name cached_file_path temporary_cache_path="$GEM_HOME/temporary-cache" live_cache_path="$GEM_HOME/cache" mkdir -p "$temporary_cache_path" rvm_log "Moving active gems into temporary cache..." while read gem_name version _platforms do cached_gem_name="${gem_name}-${version}.gem" cached_file_path="${live_cache_path}/${cached_gem_name}" if [[ -f "$cached_file_path" ]]; then mv "$cached_file_path" "${temporary_cache_path}/${cached_gem_name}" fi done < <( GEM_PATH="$GEM_HOME" __rvm_list_gems ) rvm_log "Removing live cache and restoring temporary cache..." # Switch the cache back. __rvm_rm_rf "$live_cache_path" mv "$temporary_cache_path" "$live_cache_path" return 0 } gemset_pristine() { if ( unset -f gem ; builtin command -v gem > /dev/null ) then typeset _gem _version _platforms typeset -a _failed rvm_log "Restoring gems to pristine condition..." while read _gem _version _platforms do printf "%b" "${_gem}-${_version} " if ! gem pristine ${_gem} --version ${_version} >/dev/null then _failed+=( "${_gem} --version ${_version}" ) fi done < <( GEM_PATH="$GEM_HOME" __rvm_list_gems ) if (( ${#_failed[@]} > 0 )) then rvm_error "\n'gem pristine ${_failed[*]}' failed, you need to fix this gems manually." return 1 else rvm_log "\nfinished." return 0 fi else rvm_error "'gem' command not found in PATH." return 1 fi } # Transform the list of gems one version per line __rvm_list_gems() { gem list | sed '/\*\*\*/ d ; /^$/ d; s/ (/,/; s/, /,/g; s/)//;' | awk -F ',' '{for(i=2;i<=NF;i++) print $1" "$i }' } # Loads the default gemsets for the current interpreter and gemset. gemset_initial() { typeset gemsets gemset path paths true ${rvm_gemsets_path:="$rvm_path/gemsets"} rvm_log "Importing initial gemsets for $(__rvm_env_string)." if [[ ! -d "$rvm_gemsets_path/${rvm_ruby_string//-//}/cache" ]] then mkdir -p "$rvm_gemsets_path/${rvm_ruby_string//-//}/cache" 2>/dev/null fi paths=($(__rvm_ruby_string_paths_under "$rvm_gemsets_path")) echo "paths: ${paths[@]}" for path in "${paths[@]}" do if [[ -n "$rvm_gemset_name" ]] then if [[ -s "${rvm_gemset_name}.gems" ]] then ( gems_args="${rvm_gemset_name}.gems" ; gemset_import ) fi else if [[ -s "${path}/default.gems" ]] then ( gems_args="${path}/default.gems" ; gemset_import ) fi if [[ -s "${path}/global.gems" ]] then ( rvm_create_flag=1 rvm_ruby_gem_home="${rvm_ruby_gem_home//@*/}@global" gems_args="${path}/global.gems" gemset_import ) fi fi done rvm_log "Installation of gems for $(__rvm_env_string) is complete." return 0 } search() { typeset gemspec gemspecs gem_name option environment_id ruby_string \ name gem_version gem_name="${2:-}" option="${3:-}" if [[ -z "${gem_name}" ]] then return 0 fi true "${rvm_gems_path:="$rvm_path/gems"}" gemspecs=($( find "${rvm_gems_path}" -mindepth 3 -iname "${gem_name}*.gemspec" )) -type f if [[ "${option}" != "strings" ]] then printf "%-40s %-20s %-20s\n" "environment_id" "name" "version" printf "%b" "================================================================================\n" fi for gemspec in "${gemspecs[@]}" do environment_id="${gemspec//${rvm_gems_path}\/}" environment_id="${environment_id//\/*}" ruby_string="${environment_id//@*}" gemset_name="${environment_id//${ruby_string}}" name=${gemspec//*\/} name=${name/%.gemspec} gem_version=${name//*-} if [[ "${option}" != "strings" ]] then printf "%-40s %-20s %-20s\n" "${environment_id}" "${gem_name}" "${gem_version}" else printf "%b" "${environment_id}\n" fi done } args=($*) action="${args[$__array_start]}" args[$__array_start]="" args=(${args[@]}) gems_args="$(echo ${args[@]})" # Strip trailing / leading / extra spacing. export rvm_gemset_name="${args[1]:-""}" # For wherever used. rvm_sticky_flag=1 if [[ "$action" != "globalcache" ]] && ! builtin command -v gem > /dev/null then rvm_error "'gem' was not found, cannot perform gem actions (Do you have an RVM ruby selected?)" exit 1 fi if [[ -z "$rvm_ruby_string" ]] then if echo "${GEM_HOME:-""}" | GREP_OPTIONS="" \grep "${rvm_path}" >/dev/null 2>&1 then rvm_ruby_string="${GEM_HOME##*/}" rvm_ruby_string="${rvm_ruby_string%%@*}" fi fi case "$action" in import|load) if [[ -z "${rvm_ruby_strings:-""}" ]] then gemset_import else original_env="$(__rvm_env_string)" for rvm_ruby_string in $(echo "$rvm_ruby_strings" | \tr "," " ") do __rvm_become gemset_import done __rvm_become "$original_env" unset original_env fi ;; export|dump) gemset_export ;; create|copy|delete|dir|empty|initial|list|list_all|list_strings|prune|rename|update|unpack) gemset_$action ;; name|string) gemset_name ;; gemdir|gempath|gemhome|home|path|version) gemset_info ;; pristine) gemset_$action "$@" ;; install) gem_$action "$@" ;; globalcache) gemset_globalcache "$2" ;; search) search "$@" ;; clear) rvm_log "gemset cleared." exit 0 ;; help) usage exit 0 ;; *) usage exit 1 ;; esac exit $? 1.18.57. rtfm #!/usr/bin/env bash rvm_url="https://rvm.io/" source "$rvm_path/scripts/functions/logging" if builtin command -v open >/dev/null ; then open "$rvm_url" elif builtin command -v xdg-open >/dev/null ; then xdg-open "$rvm_url" else rvm_log "Please RTFM at the URL $rvm_url" fi exit $? 1.18.58. external #!/usr/bin/env bash source "$rvm_scripts_path/base" external_automount() { external_mount_uniq $( __rvm_remove_rvm_from_path which -a ruby ) } external_grep_existing() { typeset IFS typeset -a existing IFS="|" existing=( $( for ext in $rvm_externals_path/* do if [[ -L "$ext" ]] then readlink "$ext" fi done ) ) : existing:${existing[@]}: if (( ${#existing[@]} > 0 )) then GREP_OPTIONS="" \grep -vE "${existing[@]}" else cat fi } external_mount_uniq() { typeset ruby_path typeset -a ruby_paths ruby_paths=( $( for ruby_path in "$@" do if [[ -d "${ruby_path}" && -x "${ruby_path}/bin/ruby" ]] && "${ruby_path}/bin/ruby" -rrbconfig -e "" >/dev/null 2>&1 then echo "${ruby_path}" elif [[ ! -d "${ruby_path}" && -x "${ruby_path}" ]] then "${ruby_path}" -rrbconfig -e "puts RbConfig::CONFIG['prefix']" 2>/dev/null fi done | sort -u | external_grep_existing ) ) if (( ${#ruby_paths[@]} == 0 )) then rvm_error "The given paths '$*' either do not point to a ruby installation or are already mounted." exit 1 else for ruby_path in ${ruby_paths[@]} do ( external_mount "${ruby_path}" ) || exit $? done fi } external_mount() { typeset path ruby_path prefix_path path="$1" if [[ ! -d "${path}" && -x "${path}" ]] && "${path}" --version | GREP_OPTIONS="" \grep rub >/dev/null then ruby_path="${path}" prefix_path="$("${path}" -rrbconfig -e "puts RbConfig::CONFIG['prefix']")" elif [[ -d "${path}" && -x "${path}/bin/ruby" ]] && "${path}/bin/ruby" --version | GREP_OPTIONS="" \grep rub >/dev/null then ruby_path="${path}/bin/ruby" prefix_path="$("${ruby_path}" -rrbconfig -e "puts RbConfig::CONFIG['prefix']")" if [[ "${path}" != "${prefix_path}" ]] then rvm_error "The given path '$path' contains ruby but it has different prefix '$prefix_path'." exit 2 fi else rvm_error "The given path '$path' does not point to a ruby installation." exit 3 fi if [[ -z "${rvm_ruby_name:-}" ]] then if ! external_select_name "${ruby_path}" "${prefix_path}" || [[ -z "${rvm_ruby_name:-}" ]] then rvm_error "No name selected for ruby in '$prefix_path'." exit 4 fi fi old_gem_home=$( unset GEM_HOME "${prefix_path}/bin/gem" env gemhome ) rvm_ruby_string="ext-${rvm_ruby_name}" echo "Mounting '${rvm_ruby_string}' from '${prefix_path}'" mkdir -p "$rvm_externals_path" ln -nfs "${prefix_path}" "$rvm_externals_path/$rvm_ruby_string" mkdir -p "$rvm_rubies_path/$rvm_ruby_string/bin" ln -nfs "${ruby_path}" "$rvm_rubies_path/$rvm_ruby_string/bin/ruby" rvm_create_flag=1 __rvm_use mkdir -p "$rvm_gems_path/$rvm_ruby_string@global" ln -nfs "${old_gem_home}" "$rvm_gems_path/$rvm_ruby_string" __rvm_bin_script # Import the initial gemsets, unless skipped. if (( ${rvm_skip_gemsets_flag:-0} == 0 )) then ( export rvm_gemset_name=global __rvm_run_with_env "gemsets.initial" "$rvm_ruby_string" \ "'$rvm_scripts_path/gemsets' initial" \ "$rvm_ruby_string - #importing default gemsets ($rvm_gemsets_path/)" ) else rvm_log "Skipped importing default gemsets" fi "$ruby_path" -rrbconfig \ -e 'File.open("'"$rvm_rubies_path/$rvm_ruby_string/config"'","w") { |file| RbConfig::CONFIG.each_pair{|key,value| file.write("#{key.gsub(/\.|-/,"_")}=\"#{value.gsub("$","\\$")}\"\n")} }' >/dev/null 2>&1 __rvm_record_install "$rvm_ruby_string" } external_select_name() { typeset proposed_name ruby_version ruby_path prefix_path export rvm_ruby_name ruby_path="$1" prefix_path="$2" ruby_version="$( "${ruby_path}" --version)" if [[ -x "${ruby_path}" ]] && proposed_name="$( external_propose_name "$ruby_version" )" && [[ -n "${proposed_name:-}" ]] then echo "Found '${ruby_version}' in '${prefix_path}'" printf "\n# Please enter name [${proposed_name}]: " read rvm_ruby_name printf "\n" : rvm_ruby_name:${rvm_ruby_name:=${proposed_name}}: else echo "Name not found for '${ruby_path}' in '${prefix_path}'" false fi } external_propose_name() { typeset parts __tmp1 __tmp2 parts="$( echo "$1" | sed 's/[()]//g; s/\[.*\]//;' )" case "${parts}" in (*Ruby[[:space:]]Enterprise[[:space:]]Edition*) __tmp1="${parts#* }" __tmp1="${__tmp1%% *}" __tmp2="${parts##* }" printf "ree-${__tmp1}-${__tmp2}" ;; (ruby[[:space:]]*patchlevel[[:space:]]*) __tmp1="${parts#* }" __tmp1="${__tmp1%% *}" __tmp2="${parts##*patchlevel }" __tmp2="${__tmp2%% *}" printf "ruby-${__tmp1}-p${__tmp2}" ;; (ruby[[:space:]][[:digit:]].[[:digit:]].[[:digit:]]p[[:digit:]]*) __tmp1="${parts#* }" __tmp1="${__tmp1%% *}" __tmp2="${__tmp1##+([[:digit:]\.])}" __tmp1="${__tmp1%${__tmp2}}" printf "ruby-${__tmp1}-${__tmp2}" ;; (ruby[[:space:]]*revision[[:space:]]*|ruby[[:space:]]*trunk[[:space:]]*) __tmp1="${parts#* }" __tmp1="${__tmp1%% *}" __tmp2="${parts##*trunk }" __tmp2="${__tmp2##*revision }" __tmp2="${__tmp2%% *}" printf "ruby-${__tmp1}-r${__tmp2}" ;; (ruby[[:space:]]*) __tmp1="${parts#* }" __tmp1="${__tmp1%% *}" __tmp2="${__tmp1##+([[:digit:]\.])}" __tmp1="${__tmp1%${__tmp2}}" printf "ruby-${__tmp1}-${__tmp2}" ;; (jruby[[:space:]]*) __tmp1="${parts#* }" __tmp1="${__tmp1%% *}" __tmp2="${parts#* }" __tmp2="${__tmp2#* }" __tmp2="${__tmp2%% *}" __tmp2="${__tmp2#ruby-}" __tmp2="${__tmp2//-/_}" printf "jruby-${__tmp1}-default_${__tmp2}" ;; (maglev[[:space:]]*) __tmp1="${parts#* }" __tmp1="${__tmp1%% *}" __tmp2="${parts#* }" __tmp2="${__tmp2#* }" __tmp2="${__tmp2#* }" __tmp2="${__tmp2%% *}" printf "maglev-${__tmp1}-default_${__tmp2}" ;; (rubinius[[:space:]]*) __tmp1="${parts#* }" __tmp1="${__tmp1%% *}" __tmp2="${parts#* }" __tmp2="${__tmp2#* }" __tmp2="${__tmp2%% *}" printf "rbx-${__tmp1}-default_${__tmp2}" ;; (*) false ;; esac } args=( "$@" ) action="${args[__array_start]}" unset args[__array_start] args=( "${args[@]}" ) case "${action}" in (automount) external_$action ;; (mount|*_name) external_mount_uniq "${args[@]}" ;; (*) echo "Wrong action '$action'" ;; esac 1.18.59. extras 1.18.59.1. rails #!/usr/bin/env bash # # # # # # # # # # # # # # # # # # # # # # Copyright (c) 2011 Wayne E. Seguin <wayneeseguin@gmail.com> Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. This feature is opt-in, in order to use the functions provided below source this script in your start up from your profile(s). For example, if RVM is installed to $HOME/.rvm, you can put this in your ~/.bash_profile: [[ -s "$HOME/.rvm/scripts/extras/rails" ]] && . "$HOME/.rvm/scripts/extras/rails" enable_extendglob() { if [[ -n "${ZSH_VERSION:-}" ]] ; then setopt extendedglob else if [[ -n "${BASH_VERSION:-}" ]] ; then shopt -s extglob # Extended globs else printf "%b" "What the heck kind of shell are you running here???\n" fi fi } rails_routes() { # Usage: # # rails_routes <or list, space separated> [options] # # include string is a valid shell glob: http://mywiki.wooledge.org/glob # # options are among # # * a valid shell glob pattern # * -a <and glob> # * -o <or glob> # * -e <exclude (not) glob> # # Processing occurs as ((or list) AND (and list)) NOT (exclude list) # # Examples: # # rails_routes admin # /admin/reports/agent/:id(.:format) {:controller=>"reports", :action=>"agent"} # # rails_routes "P@(OS|U)T" # POST /current(.:format) {:action=>"create", :controller=>"current"} # PUT /current/:id(.:format) {:action=>"update", :controller=>"current"} # # or, equivalently, rails_routes POST -o PUT # # List all routes containing admin but not test # rails_routes admin -e test # # rails_routes enable_extendglob typeset md5_current md5_cached cache_file routes typeset -a ands ors nots while [[ $# -gt 0 ]] ; do token="$1" ; shift case "$token" in --trace) set -o xtrace export PS4="+ \${BASH_SOURCE##\${rvm_path:-}} : \${FUNCNAME[0]:+\${FUNCNAME[0]}()} ;; -a|and) ands=(${ands[@]} "$1") shift ;; \${LINENO} > " -o|or) ors=(${ors[@]} "$1") shift ;; -e|exclude) nots=(${exclude[@]} "$1") shift ;; *) # Default is or. ors=(${ors[@]} "$token") ;; esac done [[ -d tmp/rake ]] || mkdir -p "tmp/rake" cache_file="tmp/rake/routes" if ! builtin command -v rake >/dev/null 2>&1 ; then printf "%b" "ERROR: rake not found.\n" >&2 return 1 fi case $(uname) in Linux) md5="md5sum" ;; Darwin) md5="/sbin/md5 -q" ;; *) printf "%b" "ERROR: Unknown OS Type.\n" >&2 ; esac return 1 ;; md5_current=$($md5 config/routes.rb) md5_current=${md5%% *} if [[ -s "$cache_file" && -s "$cache_file.md5" ]]; then md5_cached=$(cat -v "${cache_file}.md5") md5_cached=${md5%% *} else md5_cached="" fi if [[ -s "$cache_file" && $md5_current == $md5_cached ]]; then routes=$(cat -v "$cache_file") else routes=$(rake routes 2>/dev/null) if [[ $? -gt 0 ]]; then printf "%b" "ERROR: There was an error running 'rake routes', does your application load console properly?" >&2 return 1 else printf "%b" "$md5_current" > "${cache_file}.md5" printf "%b" "$routes" > "$cache_file" fi fi routes="${routes#\|\(in *\)}" orig_ifs="$IFS" condition="${ors[@]}" condition="*${condition// /*|*}*" IFS=" " # ORs results=() for route in ${routes} ; do eval "case '${route}' in (${condition}) results=(\"${results[@]}\" \"${route}\") ;; esac" done routes=(${results[@]}) # ANDs results=() for condition in "${ands[@]}" ; do for route in ${routes[@]} ; do if [[ ${route} == ${condition} ]]; then results=(${results[@]} ${route}) fi done routes=(${results[@]}) results=() done # NOTs results=() for condition in "${nots[@]}" ; do for route in ${routes[@]} ; do if [[ ${route} != *${condition}* ]]; then results=(${results[@]} ${route}) fi done routes=(${results[@]}) results=() done for route in ${routes[@]} ; do printf "%b" "${route}\n" done IFS="$orig_ifs" } # # r - Rails scripts helper function. # r() { typeset action args action="$1" ; shift args="$@" enable_extendglob case "$action" in c|console) action=console ;; d|db) action=dbconsole ;; g|generate) action=generate ;; d|destroy) action=destroy ;; s|server) action=server ;; r|routes) rails_routes $args return $? ;; n|new) rails_version=$(rails -v) rails_version=${rails_version##* } rails_version=${rails_version%%.*} if [[ $rails_version -ge 3 ]]; then rails new $args elif [[ $rails_version == 1 || $rails_version == 2 ]] ; then rails $args fi ;; (*(-)@(h|?|help)) action="-h" ;; (*(-)@(v|V|version)) action="-h" ;; usage) printf "%b" " r - Rails shell convenience function Usage: r [action] Actions: c d c s r - Start Start rails rails rails a Rails Console a database console generate server routes <include filter glob> [-e <exclude filter glob>] \n" ;; esac if [[ -s ./script/rails ]] ; then ruby ./script/rails $action $args elif [[ -s ./script/$action ]] ; then ruby ./script/$action $args else printf "%b" "ERROR: rails $action not found!!!" fi return 0 } 1.18.60. zsh 1.18.60.1. Completion 1.18.60.1.1. _rvm #compdef rvm typeset curcontext state line cmds ret curcontext="$curcontext" ret=1 _arguments -C \ '(- 1 *)'{-v,--version}'[display version information]' \ '(-l|--level)'{-l,--level}'+[patch level to use with rvm use / install]:number' \ '(--bin)--bin[path for binaries to be placed (~/.rvm/bin/)]:path:_files' \ '(--source)--source[src directory to use (~/.rvm/src/)]:path:_files' \ '(--archives)--archives[directory for downladed files (~/.rvm/archives/)]:path:_files' \ '-S[Specify a script file to attempt to load and run (rubydo)]:file:_files' \ '-e[Execute code from the command line]:code' \ '(-G)-G[root gem path to use]:path:_files' \ '(--gems)--gems[Used to set the gems_flag, use with remove to remove gems]' \ '(--archive)--archive[Used to set the archive_flag, use with remove to remove archive]' \ '(--patch)--patch[With MRI Rubies you may specify one or more full paths to patches]' \ '(-C|--configure)'{-C,--configure}'=[custom configure options]' \ '(--nice)--nice[process niceness (for slow computers, default 0)]:number' \ '(--ree)--ree-options[Options passed directly to ree ./installer on the command line]:options' \ '(--head)--head[with update, updates rvm to git head version]' \ '(--rubygems)--rubygems[with update, updates rubygems for selected ruby]' \ '(--default)--default[with ruby select, sets a default ruby for new shells]' \ '(--debug)--debug[Toggle debug mode on for very verbose output]' \ '(--trace)--trace[Toggle trace mode on to see EVERYTHING rvm is doing]' \ '(--force)--force[Force install, even given ruby is already install]' \ '(--summary)--summary[Used with rubydo to print out a summary of the commands run]' \ '(--latest)--latest[with gemset --dump skips version strings for latest gem]' \ '(--gems)--gems[with uninstall/remove removes gems with the interpreter]' \ '(--docs)--docs[with install, attempt to generate ri after installation]' \ '(--reconfigure)--reconfigure[Force ./configure on install even if Makefile already exists]' \ '1: :->cmds' \ '*: :->args' && ret=0 case $state in cmds) cmds=( ${(f)"$(_call_program commands rvm help 2> /dev/null | sed -e '/^== Action/,/^== Implementation/!d; / :: /!d; s/^[ *]*\([^ ]*\) *:: *\(.*\)/\1:\2/')"} ) cmds+=( $(rvm list strings) ) _describe -t commands 'rvm command' cmds && ret=0 ;; args) case $line[1] in (use|uninstall|remove|list) if (( CURRENT == 3 )); then # See if weve made it to the @; eg, 1.9.2@ if ! GREP_OPTIONS="" \grep '@' <<< "${line[CURRENT-1]}" >/dev/null ; then _values -S , 'rubies' \ $(rvm list strings | sed -e 's/ruby-\([^) ]*\)-\([^) ]*\)/ruby-\1-\2 \1-\2 \1/g') \ default system $(rvm alias list | cut -d' ' -f1) && ret=0 else # Construct a full version string for each of the gemsets. # Eg, 1.9.2@min 1.9.2@rail3 … _values -S , 'gemsets' \ $(rvm ${line[CURRENT-1]%%@*} gemset list | awk '/^[ -_[:alnum:]]+$/ {print "'${line[CURRENT-1]%%@*}'@"$1}') fi fi ;; (install|fetch) _values -S , 'rubies' $(rvm list known_strings) && ret=0 ;; gemset) if (( CURRENT == 3 )); then _values 'gemset_commands' $(rvm gemset | sed -e '/create/!d; s/^.*[{]\(.*\)[}].*$/\1/; s/,/ /g') else #_values -S , 'gemsets' $(rvm gemset list | GREP_OPTIONS="" \grep -v gemset 2>/dev/null) _values -S , 'gemsets' $(rvm gemset list | GREP_OPTIONS="" \grep -Ev '(gemset|info)' 2>/dev/null | awk '/^[ _[:alnum:]]+$/ {print '$1'}') fi ret=0 ;; package) if (( CURRENT == 3 )); then _values 'package_commands' $(rvm package | sed -e '/Usage/!d; s/^.*[{]\(.*\)[}] [{].*$/\1/; s/,/ /g') else _values 'packages' $(rvm package | sed -e '/Usage/!d; s/^.*[}] [{]\(.*\)[}].*$/\1/; s/,/ /g') fi ret=0 ;; *) (( ret )) && _message 'no more arguments' ;; esac ;; esac return ret 1.18.61. functions 1.18.61.1. implode #!/usr/bin/env bash # Remove binaries. __rvm_implode_binaries() { # Load inside a subshell to avoid polutting the current shells env. ( source "$rvm_scripts_path/base" rvm_log "Removing rvm-shipped binaries (rvm-prompt, rvm, rvm-sudo rvm-shell and rvm-auto-ruby)" for entry in "$rvm_bin_path/"{rvm-prompt,rvm,rvmsudo,rvm-shell,rvm-auto-ruby} ; do __rvm_rm_rf "$entry" done rvm_log "Removing rvm wrappers in $rvm_bin_path" \find "$rvm_bin_path" -type l | while read symlinked_rvm_file; do if [[ "$(readlink "$symlinked_rvm_file")" == "$rvm_wrappers_path/"* ]]; then __rvm_rm_rf "$symlinked_rvm_file" fi done unset symlinked_rvm_file ) } # Implode removes the entire rvm installation under $rvm_path, including removing wrappers. __rvm_implode() { while : ; do rvm_warn "Are you SURE you wish for rvm to implode?\ \nThis will recursively remove $rvm_path and other rvm traces?\ \n(type 'yes' or 'no')> " read response if [[ "yes" == "$response" ]] ; then if [[ "/" == "$rvm_path" ]] ; then rvm_error "remove '/' ?!... Ni!" else if [[ -d "$rvm_path" ]] ; then __rvm_implode_binaries rvm_log "Hai! Removing $rvm_path" for file in /etc/profile.d/rvm.sh $rvm_man_path/man1/rvm.1* $rvm_path/ ; do __rvm_rm_rf $file ; done echo "$rvm_path has been removed." if [[ "$rvm_path" == "/usr/local/rvm"* && -f "/usr/local/lib/rvm" ]]; then rvm_log "Removing the rvm loader at /usr/local/lib/rvm" fi printf "%b" "rvm has been fully removed. Note you may need to manually remove /etc/rvmrc and ~/.rvmrc if they exist still.\n" else rvm_log "It appears that $rvm_path is already non existant." fi fi break elif [[ "no" == "$response" ]] ; then rvm_log "Psychologist intervened, cancelling implosion, crisis avoided :)" break fi done return 0 } 1.18.61.2. reset #!/usr/bin/env bash # Reset any rvm gathered information about the system and its state. # rvm will refresh the stored information the next time it is called after reset. __rvm_reset() { typeset flag flags file files config configs variable __rvm_remove_rvm_from_path ; __rvm_conditionally_add_bin_path export PATH builtin hash -r flags=( default passenger editor ) for flag in "${flags[@]}"; do \rm -f "${rvm_bin_path}"/${flag}_* done for file in system default ; do if [[ -f "$rvm_path/${file}" ]] ; then \rm -f "$rvm_path/${file}" fi if [[ -f "$rvm_path/config/${file}" ]] ; then \rm -f "$rvm_path/config/${file}" fi if [[ -f "$rvm_environments_path/${file}" ]] ; then \rm -f "$rvm_environments_path/${file}" fi done # Go back to a clean state. __rvm_use_system __rvm_unset_ruby_variables __rvm_unset_exports configs=(system_ruby system_gem_path system_user_gem_path) for system_config in "${configs[@]}" ; do "$rvm_scripts_path/db" "$rvm_user_path/db" "$system_config" "delete" done files=(ruby gem rake irb $(cd "${rvm_bin_path}" ; \ find . -mindepth 1 -maxdepth 1 -iname 'default*' -type f \ | \sed -e 's#./##g')) for file in "${files[@]}"; do if [[ -f "${rvm_bin_path}/$file" ]] ; then \rm -f "${rvm_bin_path}/$file" fi done return 0 } 1.18.61.3. utility #!/usr/bin/env bash if [[ -z "${rvm_tar_command:-}" ]] then # check for the right tar to use if builtin command -v gtar >/dev/null then rvm_tar_command=gtar else rvm_tar_command=tar fi fi if [[ ! " ${rvm_tar_options:-} " =~ " --no-same-owner " ]] && \ $rvm_tar_command --help | GREP_OPTIONS="" \grep -- --no-same-owner >/dev/null then rvm_tar_options="${rvm_tar_options:-} --no-same-owner" rvm_tar_options="${rvm_tar_options## }" fi # # Functions RVM is built on # # match <value> <string|glob> match() { case "$1" in $2) return 0 ;; *) return 1 ;; esac } printenv_null() { if printenv --null >/dev/null 2>/dev/null then printenv --null else # this messes with escape sequences but allows new lines in variables printenv | sed '/=/ { s/=.*$//; p; }; d;' | while read name do zero="\0" eval "eval \"printf '%b' '$name=\$$name$zero'\"" done fi } is_a_function() { typeset -f $1 >/dev/null 2>&1 || return $? } # # RVM specific functions. # __rvm_warn_on_rubyopt() { if [[ -n "${RUBYOPT:-""}" ]]; then rvm_warn \ "Please note: You have the RUBYOPT environment variable set and this \ may interfere with normal rvm operations. We sugges unsetting it." return 1 else return 0 fi } __rvm_strings() { typeset strings ruby_strings ruby_strings=($(echo ${rvm_ruby_args:-$rvm_ruby_string})) for rvm_ruby_string in "${ruby_strings[@]}" ; do strings="$strings $(__rvm_select ; echo $rvm_ruby_string)" done echo $strings return 0 } # Return a list of directories under a given base path. # Derived from rvm_ruby_string. __rvm_ruby_string_paths_under() { typeset path part parts path="${1%/}" # Strip off any trailing slash parts=(${rvm_ruby_string//-/ }) # Strip white space. echo "$path" for part in "${parts[@]}" do path="$path/$part" echo "$path" done return 0 } # Run a specified command and log it. __rvm_run() { typeset name log temp_log_path _command message true ${rvm_debug_flag:=0} ${rvm_niceness:=0} name="${1:-}" _command="${2:-}" message="${3:-}" if [[ -n "$message" ]] then rvm_log "$message" fi if (( rvm_debug_flag > 0 )) then rvm_debug "Executing: $_command" fi if [[ -n "${rvm_ruby_string:-}" ]] then temp_log_path="${rvm_log_path}/$rvm_ruby_string" else temp_log_path="${rvm_log_path}" fi log="$temp_log_path/$name.log" if [[ ! -d "${log%\/*}" ]] then \mkdir -p "${log%\/*}" fi if [[ ! -f "$log" ]] then \touch "$log" # for zsh :( fi # TODO: Allow an 'append_flag' setting? printf "%b" "[$(date +'%Y-%m-%d %H:%M:%S')] $_command\n" > "$log" if (( rvm_niceness > 0 )) then _command="nice -n $rvm_niceness $_command" fi eval "$_command" >> "$log" 2>&1 result=$? if (( result > 0 )) then rvm_error "Error running '$_command', please read $log" fi return ${result} } # Output the current ruby's rvm source path. __rvm_source_dir() { if [[ ${rvm_ruby_selected_flag:-0} -eq 0 ]] then __rvm_select fi if [[ -z "$rvm_ruby_src_path" ]] then rvm_error "No source directory exists for the default implementation." else echo "$rvm_ruby_src_path" fi return 0 } # Output an inspection of selected 'binary' scripts, based on CLI selection. __rvm_inspect() { for binary in $rvm_ruby_args do actual_file="$(unset -f gem ; builtin command -v gem )" rvm_log "$actual_file:" if [[ ${rvm_shebang_flag:-0} -eq 1 ]] then \head -n 1 < "$actual_file" fi if [[ ${rvm_env_flag:-0} -eq 1 ]] then \awk '/ENV/' < "$actual_file" fi if [[ ${rvm_path_flag:-0} -eq 1 ]] then \awk '/PATH/' < "$actual_file" fi if [[ ${rvm_head_flag:-0} -eq 1 ]] then \head -n 5 < "$actual_file" fi if [[ ${rvm_tail_flag:-0} -eq 1 ]] then \tail -n 5 < "$actual_file" fi if [[ ${rvm_all_flag:-0} -eq 1 ]] then \cat $actual_file fi done return 0 } # Strip whitespace and normalize it all. __rvm_strip() { \sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' -e 's/[[:space:]]\{1,\}/ /g' return $? } __rvm_remove_from_path() { export PATH PATH=":$PATH:" PATH="${PATH//:$1:/:}" PATH="${PATH//::/:}" PATH="${PATH%:}" PATH="${PATH#:}" } __rvm_add_to_path() { export PATH if (( $# != 2 )) || [[ -z "$2" ]] then rvm_error "__rvm_add_to_path requires two parameters" return 1 fi __rvm_remove_from_path "$2" case "$1" in prepend) PATH="$2:$PATH" ;; append) PATH="$PATH:$2" ;; #*) anything else will just remove it from PATH - not adding back esac if [[ -n "${rvm_user_path_prefix:-}" ]] then __rvm_remove_from_path "${rvm_user_path_prefix}" PATH="${rvm_user_path_prefix}:$PATH" fi builtin hash -r } is_parent_of() { typeset name pid ppid pname name=$1 pid=$2 while [[ -n "$pid" && "$pid" != "0" ]] do read ppid pname < <(ps -p $pid -o ppid= -o comm=) if [[ -n "$ppid" && -n "$pname" ]] then if [[ "$pname" == "$name" ]] then echo $pid return 0 else pid=$ppid fi else break fi done return 1 } rvm_is_a_shell_function() { if (( ${rvm_is_not_a_shell_function:-0} > 0 )) && [[ "${1:-}" != "no_warning" ]] then if rvm_pretty_print stderr then printf "%b" "\n${rvm_notify_clr:-}RVM is not a function, selecting rubies with '${rvm_error_clr:-}rvm use ...${rvm_notify_clr:-}' will not work.${rvm_reset_clr:-}\n" >&2 else printf "%b" "\nRVM is not a function, selecting rubies with 'rvm use ...' will not work.\n" >&2 fi if is_parent_of gnome-terminal $$ >/dev/null then rvm_log "Please visit https://rvm.io/integration/gnome-terminal/ for a solution.\n" >&2 else rvm_log "You need to change your terminal settings to allow shell login. Please visit https://rvm.io/workflow/screen/ for example.\n" >&2 fi fi return ${rvm_is_not_a_shell_function:-0} } __rvm_detect_xcode_version() { typeset version_file for version_file in \ /Applications/Xcode.app/Contents/version.plist \ /Developer/Applications/Xcode.app/Contents/version.plist do if [[ -f $version_file ]] then if [[ -x /usr/libexec/PlistBuddy ]] then /usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" $version_file else sed -n '/<key>CFBundleShortVersionString<\/key>/{n; s/^.*>\(.*\)<.*$/\1/; p;}' < $version_file fi return 0 fi done if builtin command -v xcodebuild >/dev/null then xcodebuild -version | sed -n '/Xcode/ {s/Xcode //; p;}' fi } __rvm_detect_xcode_version_is() { [[ "$(__rvm_detect_xcode_version)" == "$1" ]] || return 1 } __rvm_version_compare() { typeset v1d v2d dots counter IFS typeset -a transformer counter=1 IFS="+" # to put + in transformer ;) v1d=$( printf -- $1 | GREP_OPTIONS="" \grep -o '\.' | wc -l ) v2d=$( printf -- $3 | GREP_OPTIONS="" \grep -o '\.' | wc -l ) if [[ $v1d -ge $v2d ]] then dots=$v1d else dots=$v2d fi while (( dots >= 0 )) do transformer+=( "$(( 256 ** dots-- ))*\$$((counter++))" ) done eval "$( printf printf printf printf printf )" '[[ '; $1 | \awk -F. "{ printf ${transformer[*]} }"; -- " $2 "; $3 | \awk -F. "{ printf ${transformer[*]} }"; ' ]]' } __function_on_stack() { typeset fun for fun in "$@" do if [[ " ${FUNCNAME[*]} " =~ " $fun " ]] then return 0 fi done return $# } __rvm_pager_or_cat_v() { eval "${PAGER:-cat -v} '$1'" } 1.18.61.4. init #!/usr/bin/env bash __rvm_load_rvmrc() { typeset _file typeset -a rvm_rvmrc_files if (( ${rvm_ignore_rvmrc:=0} == 1 )) then return 0 fi : rvm_stored_umask:${rvm_stored_umask:=$(umask)} rvm_rvmrc_files=("/etc/rvmrc" "$HOME/.rvmrc") if [[ -n "${rvm_prefix:-}" ]] && ! [[ "$HOME/.rvmrc" -ef "${rvm_prefix}/.rvmrc" ]] then rvm_rvmrc_files+=( "${rvm_prefix}/.rvmrc" ) fi for _file in "${rvm_rvmrc_files[@]}" do if [[ -s "$_file" ]] then if GREP_OPTIONS="" \grep '^\s*rvm .*$' "$_file" >/dev/null 2>&1 then rvm_error " $_file is for rvm settings only. rvm CLI may NOT be called from within $_file. Skipping the loading of $_file " return 1 else source "$_file" fi fi done return 0 } # Initialize rvm, ensuring that the path and directories are as expected. __rvm_initialize() { export rvm_ruby_load_path rvm_ruby_require rvm_ruby_load_path="." rvm_ruby_require="" true ${rvm_scripts_path:="$rvm_path/scripts"} source "$rvm_scripts_path/base" __rvm_clean_path __rvm_conditionally_add_bin_path export PATH if [[ ! -d "${rvm_tmp_path:-/tmp}" ]] then command mkdir -p "${rvm_tmp_path}" fi return 0 } 1.18.61.5. bundler #!/usr/bin/env bash 1.18.61.6. group #!/usr/bin/env bash add_user_to_rvm_group() { echo "Adding user '$user' to the RVM group '${rvm_group_name}'" case "$(uname)" in "OpenBSD") usermod -G "$rvm_group_name" "$user" ;; "FreeBSD") pw usermod "$user" -G "$rvm_group_name" ;; "Linux") if [[ -f "/etc/SuSE-release" ]] ; then groupmod -A "$user" "$rvm_group_name" else /usr/sbin/usermod -a -G "$rvm_group_name" "$user" fi ;; "Darwin") dscl . -append "/Groups/$rvm_group_name" GroupMembership "$user" ;; "SunOS") groups="$(id -G "$user") \"$rvm_group_name\"" usermod -G "${groups// /, }" "$user" ;; esac return 0 } # TODO: Remove this... it is now replaced with rvm group cli api. setup_rvm_group_users() { case "$(uname)" in "Darwin") usernames=$(dscl . -search /Users PrimaryGroupID 20 | GREP_OPTIONS="" \grep PrimaryGroupID | cut -f 1) ;; *) usernames=($(GREP_OPTIONS="" \grep -xF -f <(cat /etc/passwd | cut -d: -f1) <(find /home -mindepth 1 -maxdepth 1 -type d | cut -d '/' -f 3))) ;; esac for user in ${usernames[@]} do if ! groups "$user" | GREP_OPTIONS="" \grep 'rvm' >/dev/null 2>&1 then printf "%b" "Ensuring '$user' is in group '$rvm_group_name'\n" add_user_to_rvm_group $user fi done } 1.18.61.7. state #!/usr/bin/env bash # Save or restore the rvm's state. This is a toggle action. # Meant for use before and after an operation that might reset # the currently selected ruby. # TODO: Determine if we should a) yank this out or b) actually use it :) __rvm_state() { if [[ -z "$rvm_state" ]] ; then rvm_state="$(__rvm_env_string)" rvm_state="${rvm_state:-"system"}" if [[ -n "$1" ]]; then rvm_ruby_string="$1" __rvm_select __rvm_use fi else rvm_ruby_string="$rvm_state" __rvm_select __rvm_use unset rvm_state fi return 0 } 1.18.61.8. install #!/usr/bin/env bash __rvm_record_install() { typeset recorded_ruby_name rvm_install_record_file rvm_install_command [[ -z "$1" ]] && return recorded_ruby_name="$("$rvm_scripts_path/tools" strings "$1")" rvm_install_record_file="$rvm_user_path/installs" rvm_install_command=$(printf "%b" "$recorded_ruby_name $rvm_install_args\n") [[ ! -f "$rvm_install_record_file" ]] && \touch "$rvm_install_record_file" \rm -f "$rvm_install_record_file.tmp" GREP_OPTIONS="" \grep -v "^$recorded_ruby_name " < "$rvm_install_record_file" \ > "$rvm_install_record_file.tmp" echo "$rvm_install_command" >> "$rvm_install_record_file.tmp" \rm -f "$rvm_install_record_file" \mv "$rvm_install_record_file.tmp" "$rvm_install_record_file" return 0 } __rvm_remove_install_record() { typeset recorded_ruby_name rvm_install_record_file recorded_ruby_name="$("$rvm_scripts_path/tools" strings "$1")" rvm_install_record_file="$rvm_user_path/installs" if [[ -s "$rvm_install_record_file" ]]; then \mv "$rvm_install_record_file" "$rvm_install_record_file.tmp" GREP_OPTIONS="" \grep -v "^$recorded_ruby_name " < "$rvm_install_record_file.tmp" \ > "$rvm_install_record_file" \rm -f "$rvm_install_record_file.tmp" fi return 0 } __rvm_recorded_install_command() { typeset recorded_ruby_name recorded_ruby_match recorded_ruby_name="$("$rvm_scripts_path/tools" strings "$1" \ | awk -F"${rvm_gemset_separator:-"@"}" '{print $1}')" [[ -z "$recorded_ruby_name" ]] && return 1 recorded_ruby_match="^$recorded_ruby_name " if [[ -s "$rvm_user_path/installs" ]] \ && GREP_OPTIONS="" \grep "$recorded_ruby_match" "$rvm_user_path/installs" >/dev/null 2>&1 ; then GREP_OPTIONS="" \grep "$recorded_ruby_match" < "$rvm_user_path/installs" | head -n1 else return 1 fi return $? } 1.18.61.9. env #!/usr/bin/env bash # # Environment manipulation functions. # __rvm_default_flags() { true ${rvm_head_flag:=0} ${rvm_delete_flag:=0} } __rvm_nuke_rvm_variables() { unset rvm_head_flag $(env | awk -F= '/^rvm_/{print $1" "}') } # Unset ruby-specific variables __rvm_unset_ruby_variables() { # unset rvm_ruby_flag $(env | awk -F= '/^rvm_ruby_/{printf $1" "}') unset rvm_env_string rvm_ruby_string rvm_ruby_strings rvm_ruby_binary rvm_ruby_gem_home rvm_ruby_gem_path rvm_ruby_home rvm_ruby_interpreter rvm_ruby_irbrc rvm_ruby_log_path rvm_ruby_major_version rvm_ruby_minor_version rvm_ruby_package_name rvm_ruby_patch_level rvm_ruby_release_version rvm_ruby_repo_url rvm_ruby_repo_branch rvm_ruby_revision rvm_ruby_selected_flag rvm_ruby_tag rvm_ruby_version rvm_ruby_load_path rvm_ruby_require rvm_head_flag rvm_ruby_package_file rvm_ruby_configure rvm_ruby_name rvm_ruby_url rvm_ruby_global_gems_path rvm_ruby_args rvm_ruby_name rvm_llvm_flag __rvm_load_rvmrc # restore important variables } # TODO: Should be able to... # Unset both rvm variables as well as ruby-specific variables # Preserve gemset if 'rvm_sticky' is set # (persist gemset unless clear is explicitely called). __rvm_cleanse_variables() { __rvm_unset_ruby_variables if [[ ${rvm_sticky_flag:-0} -eq 1 ]] ; then export rvm_gemset_name else unset rvm_gemset_name fi unset rvm_env_string rvm_ruby_string rvm_action rvm_irbrc_file rvm_command rvm_error_message rvm_force_flag rvm_all_flag rvm_reconfigure_flag rvm_make_flags rvm_bin_flag rvm_import_flag rvm_export_flag rvm_self_flag rvm_gem_flag rvm_rubygems_flag rvm_debug_flag rvm_delete_flag rvm_summary_flag rvm_test_flag _rvm_spec_flag rvm_json_flag rvm_yaml_flag rvm_shebang_flag rvm_env_flag rvm_tail_flag rvm_use_flag rvm_dir_flag rvm_list_flag rvm_empty_flag rvm_file_name rvm_benchmark_flag rvm_clear_flag rvm_name_flag rvm_verbose_flag rvm_user_flag rvm_system_flag rvm_configure_flags rvm_uninstall_flag rvm_install_flag rvm_llvm_flag rvm_ruby_bits rvm_sticky_flag rvm_rvmrc_flag rvm_gems_flag rvm_only_path_flag rvm_docs_flag rvm_ruby_aliases rvm_patch_names rvm_install_args rvm_dump_environment_flag rvm_ruby_alias rvm_static_flag rvm_archive_extension rvm_hook rvm_ruby_name # rvm_gemsets_path rvm_user_path rvm_wrappers_path rvm_patches_path rvm_docs_path rvm_examples_path rvm_rubies_path rvm_usr_path rvm_src_path rvm_tmp_path rvm_lib_path rvm_repos_path rvm_log_path rvm_help_path rvm_environments_path rvm_archives_path __rvm_load_rvmrc # restore important variables } # Add bin path if not present __rvm_conditionally_add_bin_path() { if printf "%b" "${PATH//:/ }" | GREP_OPTIONS="" \grep -vF "${rvm_bin_path}" >/dev/null 2>&1 then case "${rvm_ruby_string:-"system"}" in system) PATH="$PATH:${rvm_bin_path}" ;; *) PATH="${rvm_bin_path}:$PATH" ;; esac builtin hash -r fi return 0 } __rvm_load_environment() { typeset string string="$1" if [[ -f "$rvm_environments_path/$string" ]]; then # Restore the path to it's state minus rvm __rvm_remove_rvm_from_path # source the environment file \. "$rvm_environments_path/$string" if [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] then \. "${rvm_path:-$HOME/.rvm}/hooks/after_use" fi # clear the PATH cache builtin hash -r elif [[ -n "$string" ]] ; then rvm "$string" else : # TODO: This should have some error handling in the context. fi return 0 } __rvm_export() { # extract the variable name from the first arg. typeset name name=${1%%=*} # store the current value, to be restored later. builtin export rvm_old_$name=${!name} # pass-through the return value of the builtin. export "$@" return $? } __rvm_unset_exports() { typeset wrap_name name value while IFS== read -d "" wrap_name value do case "$wrap_name" in rvm_old_*) name=${wrap_name#rvm_old_} if [[ -n "${value:-}" ]] then export $name="${value}" else unset $name fi unset $wrap_name ;; esac done < <(printenv_null) } # Clean all *duplicate* items out of the path. (keep first occurrence of each) __rvm_clean_path() { PATH="$(printf "%b" "$PATH" \ | awk -v RS=: -v ORS=: '!($0 in a){a[$0];print}')" PATH="${PATH/%:/}" # Strip trailing : if it exists export PATH builtin hash -r } # Clean all rvm items out of the current working path. __rvm_remove_rvm_from_path() { PATH="$(printf "%b" "$PATH" \ | awk -v RS=: -v ORS=: "/${rvm_path//\//\/}/ {next} {print}")" PATH="${PATH/%:/}" # Strip trailing : if it exists export PATH builtin hash -r } 1.18.61.10. pkg #!/usr/bin/env bash install_package() { __rvm_db "${package}_url" "package_url" ( builtin cd "$rvm_src_path" rvm_log "Fetching $package-$version.$archive_format to $rvm_archives_path" case "$archive_format" in tar.gz|tgz) "$rvm_scripts_path/fetch" \ "$package_url/$package-$version.$archive_format" \ || (result=$? && return $result) __rvm_run "$package/extract" \ "$rvm_tar_command xmzf $rvm_archives_path/$package-$version.$archive_format -C $rvm_src_path ${rvm_tar_options:-}" \ "Extracting $package-$version.$archive_format to $rvm_src_path" ;; tar.bz2) "$rvm_scripts_path/fetch" \ "$package_url/$package-$version.$archive_format" \ || (result=$? && return $result) __rvm_run "$package/extract" \ "$rvm_tar_command xmjf $rvm_archives_path/$package-$version.$archive_format -C $rvm_src_path ${rvm_tar_options:-} "\ "Extracting $package-$version.$archive_format to $rvm_src_path" ;; zip) "$rvm_scripts_path/fetch" \ "$package_url/$package-$version.$archive_format" \ || (result=$? && return $result) __rvm_run "$package/extract" \ "unzip -q -o $rvm_archives_path/$package-$version.$archive_format -d $rvm_src_path/$package-$version" \ "Extracting $package-$version.$archive_format to $rvm_src_path" ;; *) printf "%b" "\nUnrecognized archive format '$archive_format'" ; return 1 esac builtin cd "$rvm_src_path/$package-$version" __rvm_add_to_path append /usr/bin if [[ ! -z "$patches" ]] ; then for patch in $(echo $patches | \tr ',' ' ') ; do __rvm_run "$package/patch" "patch -p0 -f < $patch" "Applying patch '$patch'..." if [[ $? -gt 0 ]] ; then rvm_error "Patch $patch did not apply cleanly... back to the patching board :(" ; exit 1 fi done fi if [[ "${rvm_skip_autoreconf_flag:-0}" == 0 ]] && which autoreconf >/dev/null 2>&1 && which libtoolize >/dev/null 2>&1 && [[ -f configure.ac || -f configure.in ]] then if [[ -z "${rvm_autoconf_flags:-}" ]] then if uname -s | GREP_OPTIONS="" \grep -iE 'cygwin|mingw' >/dev/null then # no symlinks on windows :( rvm_autoconf_flags="-ivf" else rvm_autoconf_flags="-is --force" fi fi __rvm_run "$package/autoreconf" "autoreconf ${rvm_autoconf_flags}" \ "Prepare $package in $rvm_src_path/$package-$version." fi __rvm_run "$package/configure" \ "${configure:-"${rvm_configure_env:-""} ./configure --prefix=\"${prefix_path:-"$rvm_usr_path"}\""} ${rvm_configure_flags:-""} $configure_flags" \ "Configuring $package in $rvm_src_path/$package-$version." unset configure_flags if [[ "$action" == "uninstall" ]] then __rvm_run "$package/make.uninstall" \ "make uninstall" \ "Uninstalling $package from $rvm_usr_path" && \ builtin cd "$rvm_src_path" && \ __rvm_run "$package/rm_src.uninstall" \ "rm -rf $rvm_src_path/$package-$version" \ "Removing ${package}-${version} from $rvm_src_path" && \ touch "$rvm_path/config/packages" "$rvm_scripts_path/db" \ "$rvm_path/config/packages" "${package}" delete else __rvm_run "$package/make" \ "make $rvm_make_flags" \ "Compiling $package in $rvm_src_path/$package-$version." && \ __rvm_run "$package/make.install" \ "make install" \ "Installing $package to $rvm_usr_path" && \ touch "$rvm_path/config/packages" "$rvm_scripts_path/db" \ "$rvm_path/config/packages" "${package}" "${version}" fi ) } readline() { package="readline" ; archive_format="tar.gz" configure="env CFLAGS=-I${rvm_usr_path}/include LDFLAGS=-L${rvm_usr_path}/lib ./configure --prefix=${rvm_usr_path} -disable-dependency-tracking --disable-static --enable-shared" version="5.2" patches="$rvm_patches_path/$package-$version/shobj-conf.patch" install_package version="6.2" patches="$rvm_patches_path/$package-$version/patch-shobj-conf.diff" install_package } iconv() { package="libiconv" ; version=1.13.1 ; archive_format="tar.gz" install_package } curl() { package="curl" ; version=7.19.7 ; archive_format="tar.gz" install_package } openssl() { package="openssl" ; archive_format="tar.gz" __rvm_db "${package}_version" "version" if [[ "Darwin" == "$(uname)" ]] ; then if [[ -n "$rvm_architectures" ]]; then if match "$rvm_architectures" "64"; then hw_cpu64bit=1 fi if match "$rvm_architectures" "ppc"; then hw_machine="Power Macintosh" fi else hw_machine=$(sysctl hw.machine | awk -F: '{print $2}' | sed 's/^ //') hw_cpu64bit=$(sysctl hw.cpu64bit_capable | awk '{print $2}') fi if [[ "Power Macintosh" == "$hw_machine" ]] ; then if [[ $hw_cpu64bit == 1 ]]; then openssl_os="darwin64-ppc-cc" else openssl_os="darwin-ppc-cc" fi else if [[ $hw_cpu64bit == 1 ]]; then openssl_os="darwin64-x86_64-cc" else openssl_os="darwin-i386-cc" fi fi configure_command="./Configure" # Anyone know WTF happened to these patches??? #patches="$rvm_patches_path/$package/Makefile.org.patch,$rvm_patches_path/$package/crypto-Makefile.patch" # Don't use -j option for make OpenSSL [[ -z "$rvm_make_flags" ]] || rvm_make_flags=$(echo "$rvm_make_flags" | sed -e "s/-j[[:space:]]*[[:digit:]]*//") else configure_command="./config" fi configure="$configure_command $openssl_os -I$rvm_usr_path/include -L$rvm_usr_path/lib --prefix=$rvm_usr_path zlib no-asm no-krb5 shared" install_package } zlib() { package="zlib" ; version="1.2.7" ; archive_format="tar.gz" install_package } autoconf() { package="autoconf" ; version="2.65" ; archive_format="tar.gz" prefix_path="$rvm_usr_path" install_package } ncurses() { package="ncurses" ; version="5.7" ; archive_format="tar.gz" configure_flags="--with-shared --disable-rpath --without-debug --without-ada --enable-safe-sprintf --enable-sigwinch -without-progs" install_package } pkgconfig() { package="pkg-config" ; version="0.23" archive_format="tar.gz" install_package } gettext() { package="gettext" ; version="0.17" ; archive_format="tar.gz" install_package } libxml2() { package="libxml2" ; version="2.7.3" ; archive_format="tar.gz" if [[ "Darwin" == "$(uname)" ]] ; then configure="./configure --prefix=$rvm_usr_path --build=i686-apple-darwin$(uname -r) --host=i686-apple-darwin$(uname -r)" fi install_package unset prefix_path } libxslt() { package="libxslt" ; version="1.1.26" ; archive_format="tar.gz" install_package unset prefix_path } libyaml() { package="yaml" ; version="0.1.4" ; archive_format="tar.gz" if [[ "Darwin" == "$(uname)" ]] then unset rvm_configure_env fi install_package } libyaml_installed() { typeset path path="${prefix_path:-${rvm_usr_path:-${rvm_path}/usr}}" if [[ "Darwin" == "$(uname)" ]] then extension="dylib" else extension="so" fi [[ -f "${path}/include/yaml.h" ]] && \find "${path}" -name "libyaml.${extension}" | GREP_OPTIONS="" \grep '.*' >/dev/null } glib() { pkgconfig gettext package="glib" ; version="2.23.1" ; archive_format="tar.gz" configure="CC=\"cc -L$rvm_usr_path/lib -I$rvm_usr_path/include\" PKG_CONFIG=\"$rvm_usr_path/bin/pkg-config\" ./configure -prefix=\"$rvm_usr_path\"" install_package } mono() { glib __rvm_mono_env package="mono" ; version="2.6.1" ; archive_format="tar.bz2" install_package } llvm() { package="llvm" version="89156" ( builtin cd $rvm_src_path if [[ ! -d "$rvm_src_path/llvm/.svn" ]] ; then __rvm_db "${package}_url" "package_url" __rvm_rm_rf "$rvm_src_path/llvm" svn co -r "$version" "$package_url" llvm builtin cd "$rvm_src_path/llvm" ./configure --enable-bindings=none UNIVERSAL=1 UNIVERSAL_ARCH="i386 x86_64" ENABLE_OPTIMIZED=1 make -j2 sudo env UNIVERSAL=1 UNIVERSAL_ARCH="i386 x86_64" ENABLE_OPTIMIZED=1 make install fi ) } reset() { unset package version archive_format patches prefix_path configure configure_flags } 1.18.61.11. rvmrc #!/usr/bin/env bash export escape_flag _first _second escape_flag=1 _first=${__array_start} _second=$[__array_start + 1] __rvm_md5_for() { if builtin command -v md5 > /dev/null; then echo "$1" | md5 elif builtin command -v md5sum > /dev/null ; then echo "$1" | md5sum | awk '{print $1}' else rvm_error "Neither md5 nor md5sum were found in the PATH" return 1 fi return 0 } __rvm_sha256_for() { if builtin command -v sha256sum > /dev/null ; then echo "$1" | sha256sum | awk '{print $1}' elif builtin command -v sha256 > /dev/null ; then echo "$1" | sha256 | awk '{print $1}' elif builtin command -v shasum > /dev/null ; then echo "$1" | shasum -a256 | awk '{print $1}' else rvm_error "Neither sha256sum nor shasum found in the PATH" return 1 fi return 0 } __rvm_md5_for_contents() { if builtin command -v md5 > /dev/null then echo "$1" | cat - "$1" | md5 elif builtin command -v md5sum > /dev/null then echo "$1" | cat - "$1" | md5sum | awk '{print $1}' else rvm_error "Neither md5 nor md5sum were found in the PATH" return 1 fi return 0 } __rvm_sha256_for_contents() { if builtin command -v sha256sum > /dev/null ; then echo "$1" | cat - "$1" | sha256sum | awk '{print $1}' elif builtin command -v sha256 > /dev/null ; then echo "$1" | cat - "$1" | sha256 | awk '{print $1}' elif builtin command -v shasum > /dev/null ; then echo "$1" | cat - "$1" | shasum -a256 | awk '{print $1}' else rvm_error "Neither sha256sum nor shasum found in the PATH" return 1 fi return 0 } __rvm_rvmrc_key() { printf "%b" "$1" | \tr '[#/.=]' _ return $? } __rvm_reset_rvmrc_trust() { if [[ "$1" == all ]] then echo "" > "$rvm_user_path/rvmrcs" else "$rvm_scripts_path/db" "$rvm_user_path/rvmrcs" \ "$(__rvm_rvmrc_key "$1")" "delete" >/dev/null 2>&1 fi } __rvm_trust_rvmrc() { __rvm_reset_rvmrc_trust "$1" "$rvm_scripts_path/db" "$rvm_user_path/rvmrcs" \ "$(__rvm_rvmrc_key "$1")" "1;$(__rvm_md5_for_contents "$1")$(__rvm_sha256_for_contents "$1")" >/dev/null 2>&1 return $? } __rvm_untrust_rvmrc() { __rvm_reset_rvmrc_trust "$1" "${rvm_scripts_path:-"$rvm_path/scripts"}/db" "$rvm_user_path/rvmrcs" \ "$(__rvm_rvmrc_key "$1")" "0;$(__rvm_md5_for_contents "$1")$(__rvm_sha256_for_contents "$1")" >/dev/null 2>&1 } __rvm_rvmrc_stored_trust() { "${rvm_scripts_path:-"$rvm_path/scripts"}/db" "$rvm_user_path/rvmrcs" \ "$(__rvm_rvmrc_key "$1")" return $? } __rvm_rvmrc_tools() { export escape_flag typeset rvmrc_action rvmrc_path saveIFS trust rvmrc_ruby escape_flag=1 rvmrc_action="$1" (( $# )) && shift || true if [[ "${rvmrc_action}" == "create" ]] then rvmrc_ruby="${1:-${MY_RUBY_HOME##*/}}" rvmrc_path="$(builtin cd "$PWD" >/dev/null 2>&1; pwd)" elif [[ "${1:-}" == "all" ]] then rvmrc_path="all" else rvmrc_path="$(builtin cd "${1:-$PWD}" >/dev/null 2>&1; pwd)" fi (( $# )) && shift || true if (( $# )) then rvmrc_path="${rvmrc_path}/$1" elif [[ -s "${rvmrc_path}/.rvmrc" ]] then rvmrc_path="${rvmrc_path}/.rvmrc" elif [[ -s "${rvmrc_path}/.versions.conf" ]] then rvmrc_path="${rvmrc_path}/.versions.conf" elif [[ -f "${rvmrc_path}/.ruby-version" ]] then rvmrc_path="${rvmrc_path}/.ruby-version" elif [[ -f "${rvmrc_path}/.rbfu-version" ]] then rvmrc_path="${rvmrc_path}/.rbfu-version" elif [[ -f "${rvmrc_path}/.rbenv-version" ]] then rvmrc_path="${rvmrc_path}/.rbenv-version" elif [[ -f "${rvmrc_path}/Gemfile" ]] then rvmrc_path="${rvmrc_path}/Gemfile" elif [[ "${rvmrc_path}" == "all" ]] then rvmrc_path="all" else rvmrc_path="${rvmrc_path}/.rvmrc" fi case "$rvmrc_action" in create) ( rvm_ruby_string="${rvmrc_ruby}" rvm_create_flag=1 __rvm_use case "${rvmrc_path}" in (*/.rvmrc|*/--rvmrc) __rvm_set_rvmrc ;; (*/.ruby-version|*/--ruby-version) __rvm_set_ruby_version ;; (*/.versions.conf|*/--versions-conf) __rvm_set_versions_conf ;; (*) rvm_error "Unrecognized project file format." return 1 ;; esac ) ;; reset) __rvm_reset_rvmrc_trust "$rvmrc_path" echo "Reset trust for $rvmrc_path" ;; trust) __rvm_trust_rvmrc "$rvmrc_path" echo "Marked $rvmrc_path as trusted" ;; untrust) __rvm_untrust_rvmrc "$rvmrc_path" echo "Marked $rvmrc_path as untrusted" ;; trusted) if [[ -f "$rvmrc_path" ]] then saveIFS=$IFS IFS=$';' trust=($(__rvm_rvmrc_stored_trust "$rvmrc_path")) IFS=$saveIFS if [[ "${trust[${_second}]:-'#'}" != "$(__rvm_md5_for_contents "$rvmrc_path")$(__rvm_sha256_for_contents "$rvmrc_path")" ]] then echo "The rvmrc at '$rvmrc_path' contains unreviewed changes." elif [[ "${trust[${_first}]}" == '1' ]] then echo "The rvmrc at '$rvmrc_path' is currently trusted." elif [[ "${trust[${_first}]}" == '0' ]] then echo "The rvmrc at '$rvmrc_path' is currently untrusted." else echo "The trustiworthiness of '$rvmrc_path' is currently unknown." fi else echo "There is no $rvmrc_path" fi ;; is_trusted) if [[ -f "$rvmrc_path" ]] then saveIFS=$IFS IFS=$';' trust=($(__rvm_rvmrc_stored_trust "$rvmrc_path")) IFS=$saveIFS if [[ "${trust[${_second}]:-'#'}" != "$(__rvm_md5_for_contents "$rvmrc_path")$(__rvm_sha256_for_contents "$rvmrc_path")" ]] then return 1 elif [[ "${trust[${_first}]}" == '1' ]] then return 0 else return 1 fi else return 1 fi ;; load) rvm_rvmrc_cwd="" rvm_trust_rvmrcs_flag=1 \ __rvm_project_rvmrc "$(dirname "$rvmrc_path")" "$(basename "$rvmrc_path")" ;; try_to_read_ruby) case "$rvmrc_path" in (*/.rvmrc) if ! __rvm_rvmrc_tools is_trusted "$(dirname "$rvmrc_path")" "$(basename "$rvmrc_path")" then # subprocess to not mess with current process variables ( rvm_promptless=1 __rvm_project_rvmrc "$(dirname "$rvmrc_path")" "$(basename "$rvmrc_path")" >/dev/null 2>&1 ) fi if __rvm_rvmrc_tools is_trusted "$(dirname "$rvmrc_path")" "$(basename "$rvmrc_path")" then rvm_action="${rvm_action:-use}" rvm_ruby_string="$( rvm_rvmrc_cwd="" rvm_trust_rvmrcs_flag=1 __rvm_project_rvmrc "$(dirname "$rvmrc_path")" "$(basename "$rvmrc_path")" >/dev/null 2>&1 __rvm_env_string )" rvm_ruby_strings="$rvm_ruby_string" else rvm_action="error" rvm_error_message="The give path does not contain '$(basename "$rvmrc_path")' (or it is not trusted): '$(dirname "$rvmrc_path")' rest of params: '$@'" fi ;; (*) rvm_action="${rvm_action:-use}" rvm_ruby_string="$( rvm_rvmrc_cwd="" rvm_trust_rvmrcs_flag=1 __rvm_project_rvmrc "$(dirname "$rvmrc_path")" "$(basename "$rvmrc_path")" >/dev/null 2>&1 __rvm_env_string )" rvm_ruby_strings="$rvm_ruby_string" ;; esac ;; *) echo "Usage: rvm rvmrc {trust,untrust,trusted,load,reset,is_trusted,try_to_read_ruby,create}" return 1 ;; esac unset escape_flag return $? } __rvm_check_rvmrc_trustworthiness() { typeset saveIFS trust result # Trust when they have the flag... of doom! if [[ -n "$1" && ${rvm_trust_rvmrcs_flag:-0} == 0 ]] then saveIFS="$IFS" IFS=$';' trust=( $( __rvm_rvmrc_stored_trust "$1" ) ) IFS="$saveIFS" if [[ "${trust[${_second}]:-'#'}" != "$(__rvm_md5_for_contents "$1")$(__rvm_sha256_for_contents "$1")" ]] then __rvm_ask_to_trust "$1" else [[ "${trust[${_first}]}" == '1' ]] fi fi result=$? unset escape_flag return $result } __rvm_display_rvmrc() { typeset _rvmrc_base _read_char_flag _rvmrc_base="$(basename "${_rvmrc}")" [[ -n "${ZSH_VERSION:-}" ]] && _read_char_flag=k || _read_char_flag=n printf " ==================================================================================== = %-80s = = After reading the file, you will be prompted again for 'yes or no' to set = = the trust level for this particular version of the file. = = = = %-80s = = changes, and may change the trust setting manually at any time. = ==================================================================================== (( press a key to review the ${_rvmrc_base} file )) " \ "The contents of the ${_rvmrc_base} file will now be displayed." \ "Note: You will be re-prompted each time the ${_rvmrc_base} file's contents change" builtin read -${_read_char_flag} 1 -s -r anykey printf "%b" "${rvm_warn_clr}" command cat -v "${_rvmrc}" printf "%b" "${rvm_reset_clr}" printf " ==================================================================================== = %-80s = ==================================================================================== = %-80s = = %-80s = = Note that if the contents of the file change, you will be re-prompted to = = review the file and adjust its trust settings. You may also change the = = trust settings manually at any time with the 'rvm rvmrc' command. = ==================================================================================== " \ "Viewing of ${_rvmrc} complete." \ "Trusting an ${_rvmrc_base} file means that whenever you cd into this directory," \ "RVM will run this ${_rvmrc_base} shell script." } __rvm_ask_to_trust() { typeset trusted value anykey _rvmrc _rvmrc="${1}" if [[ ! -t 0 ]] || (( ${rvm_promptless:=0} == 1 )) || [[ -n "$MC_SID" ]] then return 2 fi printf "==================================================================================== = NOTICE = ==================================================================================== = %-80s = = This is a shell script and therefore may contain any shell commands. = = = = Examine the contents of this file carefully to be sure the contents are = = safe before trusting it! ( Choose v[iew] below to view the contents ) = ==================================================================================== " \ "RVM has encountered a new or modified $(basename "${_rvmrc}") file in the current directory" trusted=0 while (( ! trusted )) do printf "Do you wish to trust this $(basename "${_rvmrc}") file? (%b)\n" "${_rvmrc}" printf "%b" 'y[es], n[o], v[iew], c[ancel]> ' builtin read response value="$(echo -n "${response}" | \tr '[[:upper:]]' '[[:lower:]]' | __rvm_strip)" case "${value:-n}" in v|view) __rvm_display_rvmrc ;; y|yes) trusted=1 ;; n|no) break ;; c|cancel) return 1 ;; esac done if (( trusted )) then __rvm_trust_rvmrc "$1" return 0 else __rvm_untrust_rvmrc "$1" return 1 fi } # Checks the rvmrc for the given directory. Note that if # argument is passed, it will be used instead of pwd. __rvm_project_rvmrc() { export __rvm_project_rvmrc_lock : __rvm_project_rvmrc_lock:${__rvm_project_rvmrc_lock:=0} : __rvm_project_rvmrc_lock:$((__rvm_project_rvmrc_lock+=1)) if (( __rvm_project_rvmrc_lock > 1 )) then return 0 # no nesting fi typeset working_dir requested_file found_file rvm_trustworthiness_result # Get the first argument or the pwd. working_dir="${1:-"$PWD"}" requested_file="${2:-}" while : do if [[ -z "$working_dir" || "$HOME" == "$working_dir" || "${rvm_prefix:-}" == "$working_dir" then if [[ -n "${rvm_current_rvmrc:-""}" ]] then __rvm_remove_rvm_from_path ; __rvm_conditionally_add_bin_path if (( ${rvm_project_rvmrc_default:-0} == 1 )) then __rvm_load_environment "default" elif [[ -n "${rvm_previous_environment:-""}" ]] then __rvm_load_environment "$rvm_previous_environment" fi unset rvm_current_rvmrc rvm_previous_environment fi break else if [[ -n "${requested_file}" && -f "$working_dir/${requested_file}" ]] then found_file="$working_dir/${requested_file}" elif [[ -f "$working_dir/.rvmrc" ]] then found_file="$working_dir/.rvmrc" elif [[ -f "$working_dir/.versions.conf" ]] then found_file="$working_dir/.versions.conf" elif [[ -f "$working_dir/.ruby-version" ]] then found_file="$working_dir/.ruby-version" elif [[ -f "$working_dir/.rbfu-version" ]] then found_file="$working_dir/.rbfu-version" elif [[ -f "$working_dir/.rbenv-version" ]] then found_file="$working_dir/.rbenv-version" elif [[ -f "$working_dir/Gemfile" ]] || "/" == "$working_dir" ]] then found_file="$working_dir/Gemfile" fi if [[ -n "${found_file}" ]] then if [[ "${rvm_current_rvmrc:-""}" != "${found_file}" ]] then if __rvm_conditionally_do_with_env __rvm_load_project_config "${found_file}" then true else rvm_trustworthiness_result=$? unset __rvm_project_rvmrc_lock return "$rvm_trustworthiness_result" fi fi break else working_dir="$(dirname "$working_dir")" fi fi done unset __rvm_project_rvmrc_lock return $? } __rvm_load_project_config() { typeset __gemfile : rvm_autoinstall_bundler_flag:${rvm_autoinstall_bundler_flag:=0} case "$1" in (*/.rvmrc) if __rvm_check_rvmrc_trustworthiness "$1" then __rvm_remove_rvm_from_path ; __rvm_conditionally_add_bin_path rvm_previous_environment="$(__rvm_env_string)" rvm_current_rvmrc="$1" __rvm_ensure_is_a_function source "$1" else return $? fi ;; (*/.versions.conf) typeset _gem _gem_names _bundle_install __rvm_ensure_is_a_function rvm_previous_environment="$(__rvm_env_string)" rvm_current_rvmrc="$1" rvm_ruby_string="$(sed -n '/^ruby=/ {s/ruby=//;p;}' < "$1")" [[ -n "${rvm_ruby_string}" ]] || return 2 rvm_gemset_name="$(sed -n '/^ruby-gemset=/ {s/ruby-gemset=//;p;}' < "$1")" rvm_create_flag=1 __rvm_use || return 3 # TODO: read env.* # how to sanitize ? _gem_names="$(sed -n '/^ruby-gem-install=/ {s/ruby-gem-install=//;p;}' < "$1")" for _gem in ${_gem_names//,/ } do # TODO: add support for versions if ! gem list | GREP_OPTIONS="" \grep "^${_gem} " > /dev/null then gem install "${_gem}" fi done _bundle_install="$(sed -n '/^ruby-bundle-install=/ {s/ruby-bundle-install=//;p;}' < "$1")" if [[ -n "${_bundle_install}" ]] || [[ "${rvm_autoinstall_bundler_flag:-0}" == 1 ]] then if [[ "${_bundle_install}" == true ]] # prevent file named true for Gemfile then __gemfile="$(dirname $1)/Gemfile" elif [[ -f "${_bundle_install}" ]] then __gemfile="${_bundle_install}" elif [[ "${rvm_autoinstall_bundler_flag:-0}" == 1 ]] then __gemfile="$(dirname $1)/Gemfile" fi fi ;; (*/Gemfile) __rvm_ensure_is_a_function rvm_previous_environment="$(__rvm_env_string)" rvm_current_rvmrc="$1" rvm_ruby_string="$(sed -n '/^#ruby=/ {s/#ruby=//;p;}' < "$1")" [[ -n "${rvm_ruby_string}" ]] || { rvm_ruby_string="$(sed -n "/^\s*ruby/ {s/^\s*ruby//; s/[ ()'\"]//g; p;}" < "$1")" [[ -n "${rvm_ruby_string}" ]] || return 2 } rvm_gemset_name="$(sed -n '/^#ruby-gemset=/ {s/#ruby-gemset=//;p;}' < "$1")" rvm_create_flag=1 __rvm_use || return 3 # TODO: read #env.* # how to sanitize ? if [[ "${rvm_autoinstall_bundler_flag:-0}" == "1" ]] then __gemfile="$1" gem list | GREP_OPTIONS="" \grep "^bundler " > /dev/null || gem install bundler fi ;; (*/.ruby-version|*/.rbfu-version|*/.rbenv-version) __rvm_ensure_is_a_function rvm_previous_environment="$(__rvm_env_string)" rvm_current_rvmrc="$1" rvm_ruby_string="$(cat "$1")" [[ -n "${rvm_ruby_string}" ]] || return 2 if [[ -f "$(dirname $1)/.ruby-gemset" ]] then rvm_gemset_name="$(cat "$(dirname $1)/.ruby-gemset")" fi rvm_create_flag=1 __rvm_use || return 3 # "$(dirname $1)/.rbenv-vars" ... can we support those without licensing ? if [[ "${rvm_autoinstall_bundler_flag:-0}" == 1 && -f "$(dirname $1)/Gemfile" ]] then if ! gem list | GREP_OPTIONS="" \grep "^bundler " > /dev/null then gem install "bundler" fi __gemfile="$(dirname $1)/Gemfile" fi ;; (*) rvm_error "Unsupported file format for '$1'" return 1 ;; esac if [[ -n "${__gemfile:-}" && -f "${__gemfile:-}" ]] then bundle install --gemfile="${__gemfile}" | GREP_OPTIONS="" \grep -vE '^Using|Your bundle is complete' fi } __rvm_project_rvmrc_with_env() { __rvm_do_with_env __rvm_project_rvmrc "$@" } __rvm_set_versions_conf() { typeset gemset identifier if [[ -s .versions.conf ]] then mv .versions.conf .versions.conf.$(date +%m.%d.%Y-%H:%M:%S) rvm_warn ".version.conf is not empty, moving aside to preserve." fi identifier=$(__rvm_env_string) gemset=${identifier#*@} identifier=${identifier%@*} printf "%b" "ruby=$identifier " >> .versions.conf if [[ -n "$gemset" && "$gemset" != "$identifier" ]] then printf "%b" "ruby-gemset=$gemset " >> .versions.conf else printf "%b" "#ruby-gemset=my-projectit " >> .versions.conf fi printf "%b" "#ruby-gem-install=bundler rake #ruby-bundle-install=true " >> .versions.conf } __rvm_set_ruby_version() { if [[ -s .ruby-version ]] then mv .ruby-version .ruby-version.$(date +%m.%d.%Y-%H:%M:%S) rvm_warn ".ruby-version is not empty, moving aside to preserve." fi echo "$(__rvm_env_string)" >> .ruby-version } __rvm_set_rvmrc() { typeset flags identifier short_identifier gem_file true ${rvm_verbose_flag:=0} if [[ "$HOME" != "$PWD" && "${rvm_prefix:-}" != "$PWD" ]] then if (( rvm_verbose_flag )) then flags="use " fi if [[ -s .rvmrc ]] then mv .rvmrc .rvmrc.$(date +%m.%d.%Y-%H:%M:%S) rvm_warn ".rvmrc is not empty, moving aside to preserve." fi identifier=$(__rvm_env_string) short_identifier="${identifier#ruby-}" short_identifier="${short_identifier%%-*}" printf "%b" "#!/usr/bin/env bash # This is an RVM Project .rvmrc file, used to automatically load the ruby # development environment upon cd'ing into the directory # First we specify our desired <ruby>[@<gemset>], the @gemset name is optional, # Only full ruby name is supported here, for short names use: # echo \"rvm use ${short_identifier}\" > .rvmrc environment_id=\"$identifier\" # Uncomment the following lines if you want to verify rvm version per project # rvmrc_rvm_version=\"${rvm_version}\" # 1.10.1 seams as a safe start # eval \"\$(echo \${rvm_version}.\${rvmrc_rvm_version} | awk -F. '{print \"[[ \"\$1*65536+\$2*256+\$3\" -ge \"\$4*65536+\$5*256+\$6\" ]]\"}' )\" || { # echo \"This .rvmrc file requires at least RVM \${rvmrc_rvm_version}, aborting loading.\" # return 1 # } " >> .rvmrc if [[ "$identifier" =~ jruby* ]] then printf "%b" " # Uncomment following line if you want options to be set only for given project. # PROJECT_JRUBY_OPTS=( --1.9 ) # The variable PROJECT_JRUBY_OPTS requires the following to be run in shell: # chmod +x \${rvm_path}/hooks/after_use_jruby_opts " >> .rvmrc fi printf "%b" " # First we attempt to load the desired environment directly from the environment # file. This is very fast and efficient compared to running through the entire # CLI and selector. If you want feedback on which environment was used then # insert the word 'use' after --create as this triggers verbose mode. if [[ -d \"\${rvm_path:-\$HOME/.rvm}/environments\" && -s \"\${rvm_path:-\$HOME/.rvm}/environments/\$environment_id\" ]] then \\. \"\${rvm_path:-\$HOME/.rvm}/environments/\$environment_id\" [[ -s \"\${rvm_path:-\$HOME/.rvm}/hooks/after_use\" ]] && \\. \"\${rvm_path:-\$HOME/.rvm}/hooks/after_use\" || true " >> .rvmrc if [[ " $flags " =~ " use " ]] then printf "%b" " if [[ \$- == *i* ]] # check for interactive shells then echo \"Using: \$(tput setaf 2)\$GEM_HOME\$(tput sgr0)\" # show the user the ruby and gemset they are using in green else echo \"Using: \$GEM_HOME\" # don't use colors in non-interactive shells fi " >> .rvmrc fi printf "%b" "else # If the environment file has not yet been created, use the RVM CLI to select. rvm --create $flags \"\$environment_id\" || { echo \"Failed to create RVM environment '\${environment_id}'.\" return 1 } fi " >> .rvmrc for gem_file in *.gems do case "$gem_file" in (\*.gems) continue ;; esac printf "%b" " # If you use an RVM gemset file to install a list of gems (*.gems), you can have # it be automatically loaded. Uncomment the following and adjust the filename if # necessary. # # filename=\".gems\" # if [[ -s \"\$filename\" ]] # then # rvm gemset import \"\$filename\" | GREP_OPTIONS="" \grep -v already | grep -v listed | grep -v complete | sed '/^$/d' # fi " >> .rvmrc done if [[ -s Gemfile ]] then printf "%b" " # If you use bundler, this might be useful to you: # if [[ -s Gemfile ]] && { # ! builtin command -v bundle >/dev/null || # # # # # # # # # # " builtin command -v bundle | GREP_OPTIONS="" \grep \$rvm_path/bin/bundle >/dev/null } then printf \"%b\" \"The rubygem 'bundler' is not installed. Installing it now.\\\\n\" gem install bundler fi if [[ -s Gemfile ]] && builtin command -v bundle >/dev/null then bundle install | GREP_OPTIONS="" \grep -vE '^Using|Your bundle is complete' fi >> .rvmrc fi else rvm_error ".rvmrc cannot be set in your home directory.\ \nThe home .rvmrc is for global rvm settings only." fi } __rvm_project_dir_check() { [[ -n "${1:-}" && -d "$1" ]] && { [[ -f "$1/.rvmrc" && -s "$1/.rvmrc" ]] || [[ -f "$1/.versions.conf" && -s "$1/.versions.conf" ]] || [[ -f "$1/.ruby-version" && -s "$1/.ruby-version" ]] || [[ -f "$1/.rbfu-version" && -s "$1/.rbfu-version" ]] || [[ -f "$1/.rbenv-version" && -s "$1/.rbenv-version" ]] || { [[ -f "$1/Gemfile" && -s "$1/Gemfile" ]] && { GREP_OPTIONS="" \grep "^#ruby=" "$1/Gemfile" >/dev/null || GREP_OPTIONS="" \grep "^\s*ruby" "$1/Gemfile" >/dev/null } } } } 1.18.61.12. logging #!/usr/bin/env bash # Logging functions # check if user wants colors and if output goes to terminal # rvm_pretty_print_flag: # - 0|no - disabled always # - 1|auto - automatic depending if the output goes to terminal (default) # - 2|force - forced always # to select which terminal output should be checked use first param: # - stdout - for stdout (default) # - stderr - for stderr # - number - for the given terminal fd # - else - for both stdout and stderr rvm_pretty_print() { case "${rvm_pretty_print_flag:=auto}" in (0|no) return 1 ;; (1|auto) case "${TERM:-dumb}" in (dumb|unknown) return 1 ;; esac case "$1" in (stdout) [[ -t 1 ]] || return 1 ;; (stderr) [[ -t 2 ]] || return 1 ;; ([[:digit:]]) [[ -t $1 ]] || return 1 ;; (any) [[ -t 1 || -t 2 ]] || return 1 ;; (*) [[ -t 1 && -t 2 ]] || return 1 ;; esac return 0 ;; (2|force) return 0 ;; esac } case "${TERM:-dumb}" in (dumb|unknown) rvm_error_clr="" rvm_warn_clr="" rvm_debug_clr="" rvm_notify_clr="" rvm_reset_clr="" ;; (*) rvm_error_clr="$( "${rvm_scripts_path:-${rvm_pat}/scripts}/color" rvm_warn_clr="$( "${rvm_scripts_path:-${rvm_pat}/scripts}/color" rvm_debug_clr="$( "${rvm_scripts_path:-${rvm_pat}/scripts}/color" rvm_notify_clr="$( "${rvm_scripts_path:-${rvm_pat}/scripts}/color" rvm_reset_clr="$( "${rvm_scripts_path:-${rvm_pat}/scripts}/color" ;; esac rvm_error() { if rvm_pretty_print stderr then printf "%b" "${rvm_error_clr:-}$*${rvm_reset_clr:-}\n" else printf "%b" "$*\n" fi >&2 } rvm_warn() { if rvm_pretty_print stdout then printf "%b" "${rvm_warn_clr:-}$*${rvm_reset_clr:-}\n" else printf "%b" "$*\n" fi } rvm_debug() { if rvm_pretty_print stdout then printf "%b" "${rvm_debug_clr:-}$*${rvm_reset_clr:-}\n" else printf "%b" "$*\n" fi } rvm_log() { if rvm_pretty_print stdout then printf "%b" "${rvm_notify_clr:-}$*${rvm_reset_clr:-}\n" else printf "%b" "$*\n" fi } "${rvm_error_color:-red}" "${rvm_warn_color:-yellow}" "${rvm_debug_color:-magenta}" "${rvm_notify_color:-green}" "${rvm_reset_color:-reset}" )" )" )" )" )" 1.18.61.13. benchmark #!/usr/bin/env bash # Wrap the specified ruby code file in a Benchmark.bmbm block and execute it. __rvm_benchmark() { typeset old_rvm_ruby_string code="require \"benchmark\" \n \ Benchmark.bmbm do |benchmark| \n \ benchmark.report(\"${rvm_ruby_file}\") do \n" printf "%b" "\n$code" > "${rvm_tmp_path}/$$.rb" unset code cat $rvm_ruby_file >> "${rvm_tmp_path}/$$.rb" printf "%b" "\n end \nend\n" >> "${rvm_tmp_path}/$$.rb" rvm_ruby_args="${rvm_tmp_path}/$$.rb" rvm_benchmark_flag=1 rvm_action="ruby" if [[ ${rvm_debug_flag:0} -gt 0 ]] ; then printf "%b" "\n${rvm_tmp_path}/$$.rb:\n\ $(cat ${rvm_tmp_path}/$$.rb)" fi # Override ruby string stuff, pass through. old_rvm_ruby_string=$rvm_ruby_string # TODO: We can likely do this in a subshell in order to # preserve the original environment? unset rvm_ruby_string export rvm_ruby_strings "$rvm_scripts_path/set" "$rvm_action" $rvm_ruby_args ; result=$? # Restore the state pre-sets. [[ -n "$old_rvm_ruby_string" ]] && rvm_ruby_string=$old_rvm_ruby_string return ${result:-0} } 1.18.61.14. developer #!/usr/bin/env bash # # Switch between RVM installs. # Given a topic context name like "testing", looks for a directory named ".rvm.testing" # (installing a new copy of RVM in it if it doesn't already exist), then symlinks # .rvm to it. # # rvmselect testing rvmselect() { if [[ -z "${1:-}" ]] then echo "No topic context name specified (example: work )" return 0 fi typeset name name=$1 true ${rvm_path:=$HOME/.rvm} if [[ ! -L "$rvm_path" && -d "$rvm_path" ]] then printf "%b" "ERROR: $rvm_path is a directory, rename it to .<somename> first." fi if [[ ! -d "${rvm_path}.${name}" ]] then curl -L get.rvm.io | bash mv "${rvm_path}" "${rvm_path}.${name}" fi rm -f "${rvm_path}" ln -fs "${rvm_path}.${name}" "${rvm_path}" ls -al "$(basename "${rvm_path}")" | GREP_OPTIONS="" \grep "$rvm_path" | awk '/rvm/{print "=> "$NF}' return $? } 1.18.61.15. build #!/usr/bin/env bash # show the user selected compiler or return 1 __rvm_selected_compiler() { if [[ " ${rvm_configure_flags:-}" =~ " --with-gcc=" ]] then typeset __compiler __compiler="${rvm_configure_flags}" __compiler="${__compiler#*--with-gcc=}" __compiler="${__compiler% *}" echo "${__compiler}" elif [[ -n "${CC:-}" ]] then echo "${CC}" else return 1 fi } __rvm_found_compiler() { __rvm_selected_compiler || which gcc 2>/dev/null } __rvm_compiler_is_llvm() { typeset compiler if compiler=$(__rvm_found_compiler) then $compiler --version | GREP_OPTIONS="" \grep -i llvm >/dev/null else return 1 fi } __rvm_compiler_is_gcc47() { typeset compiler if compiler=$(__rvm_found_compiler) then [[ "$($compiler -dumpversion)" =~ "4.7" ]] else return 1 fi } __rvm_setup_compile_environment() { __rvm_setup_compile_environment_osx_gcc __rvm_setup_compile_environment_osx_architectures __rvm_setup_compile_environment_gcc47 } __rvm_setup_compile_environment_osx_gcc() { if [[ "Darwin" == "$(uname)" ]] && ! __rvm_selected_compiler > /dev/null then export CC # override CC if gcc-4.2 available (OSX) if [[ -x /usr/bin/gcc-4.2 ]] then CC=/usr/bin/gcc-4.2 elif which gcc-4.2 > /dev/null then CC=gcc-4.2 fi fi if [[ "${rvm_patch_names:-}" =~ *debug* ]] then rvm_force_autoconf_flag=1 fi } __rvm_setup_compile_environment_osx_architectures() { [[ -n "${rvm_architectures:-}" ]] || return 0 if [[ "${rvm_ruby_version}" =~ 1.9.* ]] then # Ruby 1.9.x supports the easy way rvm_configure_flags="${rvm_configure_flags:-} --with-arch=${rvm_architectures}" else export -a rvm_configure_env typeset architectures architecture for architecture in ${rvm_architectures//,/ } do architectures="${architectures} -arch ${architecture}" done rvm_configure_env+=( "MACOSX_DEPLOYMENT_TARGET=$(sw_vers -productVersion | awk -F'.' '{print $1"."$2}')" ) rvm_configure_env+=("CFLAGS='${architectures} -g -Os -pipe -no-cpp-precomp'") rvm_configure_env+=("CCFLAGS='${architectures} -g -Os -pipe'") rvm_configure_env+=("CXXFLAGS='${architectures} -g -Os -pipe'") rvm_configure_env+=("LDFLAGS='${architectures} -bind_at_load'") rvm_configure_env+=( "LDSHARED='cc ${architectures} -dynamiclib -undefined suppress -flat_namespace'" ) rvm_configure_env="${rvm_configure_env[*]}" if ! [[ "${rvm_patch_names:-}" =~ *osx-arch-fix* ]] then rvm_patch_names="osx-arch-fix ${rvm_patch_names:-}" fi fi } __rvm_setup_compile_environment_gcc47() { __rvm_compiler_is_gcc47 || return 0 [[ "${rvm_ruby_version}" =~ 1.8.* ]] || return 0 typeset gcc47flags gcc47flags="-O2 -fno-tree-dce -fno-optimize-sibling-calls" if [[ "${rvm_configure_env}" =~ "CCFLAGS=" ]] then rvm_configure_env="${rvm_configure_env/CCFLAGS='/CCFLAGS='${gcc47flags} }" else rvm_configure_env="CCFLAGS='${gcc47flags}' ${rvm_configure_env}" fi } __rvm_check_for_compiler() { if __rvm_selected_compiler > /dev/null && ! builtin command -v $(__rvm_selected_compiler) >/dev/null then rvm_error "You requested building with '$(__rvm_selected_compiler)' but it is not in your path." return 1 fi } # Checks for bison, returns zero iff it is found __rvm_check_for_bison() { true ${rvm_head_flag:=0} if (( rvm_head_flag > 0 )) then if ! builtin command -v bison > /dev/null then rvm_error "\nbison is not available in your path. \nPlease ensure bison is installed before compiling from head.\n" return 1 fi fi } __rvm_mono_env() { DYLD_LIBRARY_PATH="${rvm_usr_path}/lib:$DYLD_LIBRARY_PATH" C_INCLUDE_PATH="${rvm_usr_path}/include:$C_INCLUDE_PATH" ACLOCAL_PATH="${rvm_usr_path}/share/aclocal" ACLOCAL_FLAGS="-I $ACLOCAL_PATH" PKG_CONFIG_PATH="${rvm_usr_path}/lib/pkgconfig:$PKG_CONFIG_PATH" export DYLD_LIBRARY_PATH C_INCLUDE_PATH ACLOCAL_PATH ACLOCAL_FLAGS PKG_CONFIG_PATH __rvm_add_to_path prepend "${rvm_usr_path}/bin" builtin hash -r return 0 } # Returns all mri compatible (partly) ruby for use # with things like rbx etc which require a ruby be installed. __rvm_mri_rubies() { typeset versions _ruby versions="${1:-"1.8.|ree|1.9."}" for _ruby in $( find $rvm_rubies_path/ -maxdepth 1 -mindepth 1 -type d -not -type l ) do printf "%b" "${_ruby##*/}\n" done | GREP_OPTIONS="" \grep -E "$versions" } # Returns the first mri compatible (partly) ruby for use # with things like rbx etc which require a ruby be installed. __rvm_mri_ruby() { typeset versions versions="${1:-"1.8.|ree|1.9."}" _mri_rubies=( $( __rvm_mri_rubies "$versions" ) ) _current_ruby=$(__rvm_env_string) if [[ " ${_mri_rubies[*]} " =~ " ${_current_ruby} " ]] then printf "%b" "${_current_ruby}\n" else for _ruby in ${_mri_rubies[@]} do printf "%b" "${_ruby}\n" done | sort | head -n 1 fi return 0 } __rvm_ensure_has_mri_ruby() { typeset versions versions="${1:-"1.8.|ree|1.9."}" if [[ -z "$(__rvm_mri_ruby $versions)" ]] then typeset compat_result compat_result=0 if ! ( "$rvm_bin_path"/rvm install 1.8.7 ) then rvm_error " To proceed rvm requires a 1.8-compatible ruby is installed. We attempted to install 1.8.7 automatically but it failed. Please install it manually (or a compatible alternative) to proceed. " compat_result=1 fi return $compat_result fi return 0 } 1.18.61.16. irbrc #!/usr/bin/env bash # Create the irbrc for the currently selected ruby installation. __rvm_irbrc() { if [[ -d "$rvm_ruby_home" && ! -s "$rvm_ruby_irbrc" ]] ; then \cp "$rvm_scripts_path/irbrc" "$rvm_ruby_irbrc" fi return $? } 1.18.61.17. db #!/usr/bin/env bash # Query the rvm key-value database for a specific key # Allow overrides from user specifications in $rvm_user_path/db __rvm_db() { typeset value key variable key=${1:-""} key=${key#go} # Support for goruby - remove the go variable=${2:-""} if [[ -f "$rvm_user_path/db" ]] ; then value="$("$rvm_scripts_path/db" "$rvm_user_path/db" "$key")" fi if [[ -z "$value" ]] ; then value="$("$rvm_scripts_path/db" "$rvm_path/config/db" "$key")" fi if [[ -n "$value" ]] ; then if [[ -z "$variable" ]] ; then echo $value else eval "$variable='$value'" fi fi return 0 } 1.18.61.18. environment #!/usr/bin/env bash __rvm_env_string() { typeset _path _string _path="${GEM_HOME:-""}" _string="${_path//*gems\//}" _string="${_string//\/*/}" printf "%b" "${_string:-system}" } __rvm_expand_ruby_string() { typeset string current_ruby string="$1" case "${string:-all}" in all) "$rvm_scripts_path/list" strings | \tr ' ' "\n" ;; all-gemsets) "$rvm_scripts_path/list" gemsets strings ;; default-with-rvmrc|rvmrc) "$rvm_scripts_path/tools" path-identifier "$PWD" ;; all-rubies|rubies) "$rvm_scripts_path/list" rubies strings ;; current-ruby|gemsets) current_ruby="$(__rvm_env_string)" current_ruby="${current_ruby%@*}" rvm_silence_logging=1 "$rvm_scripts_path/gemsets" list strings \ | \sed "s/ (default)//; s/^/$current_ruby${rvm_gemset_separator:-@}/ ; s/@default// ;" ;; current) __rvm_env_string ;; aliases) awk -F= '{print $string}' < "$rvm_path/config/alias" ;; *) __rvm_ruby_strings_exist $( echo "$string" | \tr "," "\n" | __rvm_strip ) ;; esac } __rvm_become() { # set rvm_rvmrc_flag=0 to not create .rvmrc in random places of code typeset string rvm_rvmrc_flag string="$1" rvm_rvmrc_flag=0 [[ -n "$string" ]] && { rvm_ruby_string="$string" rvm_gemset_name="" } __rvm_use >/dev/null || return $? rvm_ruby_string="${rvm_ruby_string}${rvm_gemset_name:+${rvm_gemset_separator:-'@'}}${rvm_gemset_name:-}" return 0 } __rvm_ensure_has_environment_files() { typeset environment_id file_name directory identifier variable value variables environment_id="$(__rvm_env_string)" file_name="${rvm_environments_path}/$environment_id" if [[ ! -d "$rvm_environments_path" ]] then \mkdir -p "$rvm_environments_path" fi if [[ ! -s "$file_name" ]] || ! GREP_OPTIONS="" \grep 'rvm_env_string=' "$file_name" >/dev/null then rm -f "$file_name" printf "%b" \ "export PATH ; PATH=\"${rvm_ruby_gem_home}/bin:${rvm_ruby_global_gems_path}/bin:${rvm_ruby_home}/bin:${rvm_bin_path}:\$PATH\"\n" \ > "$file_name" for variable in rvm_env_string rvm_path rvm_ruby_string rvm_gemset_name \ RUBY_VERSION GEM_HOME GEM_PATH MY_RUBY_HOME IRBRC MAGLEV_HOME RBXOPT do eval "export $variable" eval "value=\${${variable}:-""}" if [[ -n "$value" ]] then printf "export %b ; %b='%b'\n" "${variable}" "${variable}" "${value}" >> "$file_name" else printf "unset %b\n" "${variable}" >> "$file_name" fi done fi # Next, ensure we have default wrapper files. Also, prevent it from recursing. if (( ${rvm_create_default_wrappers:=0} == 1 )) || [[ ! -f "$rvm_wrappers_path/$environment_id/ruby" ]] then # We need to generate wrappers for both the default gemset and the global gemset. for identifier in "$environment_id" "${environment_id//@*/}@global" do rvm_create_default_wrappers=1 directory="$rvm_wrappers_path/$identifier" if [[ ! -L "$directory" && ! -d "$directory" ]]; then \mkdir -p "$directory" "$rvm_scripts_path/wrapper" "$identifier" &> /dev/null fi done rvm_create_default_wrappers=0 fi return 0 } # Loop over the currently installed rubies and refresh their binscripts. __rvm_bin_scripts() { for rvm_ruby_binary in "$rvm_rubies_path"/*/bin/ruby do if [[ -x "$rvm_ruby_binary" ]] then rvm_ruby_string=$( dirname "$rvm_ruby_binary" | xargs dirname | xargs basename ) __rvm_select __rvm_bin_script fi done return 0 } # Write the bin/ wrapper script for currently selected ruby. # TODO: Adjust binscript to be able to handle all rubies, # not just the standard interpreteres. __rvm_bin_script() { "$rvm_scripts_path/wrapper" "$rvm_ruby_string" } # Runs a command in a given env. __rvm_run_with_env() { typeset name environment _command message log path name="${1:-""}" environment="${2:-""}" _command="${3:-""}" message="${4:-""}" [[ -n "$environment" ]] || environment="$(__rvm_env_string)" if [[ -n "$message" ]] ; then rvm_log "$message" ; fi if (( ${rvm_debug_flag:=0} == 1 )) then rvm_debug "Executing: $_command in environment $environment" fi path="${rvm_log_path}/$rvm_ruby_string" log="$path/$name.log" if [[ ! -d "$path" ]] then command mkdir -p "$path" fi if [[ ! -f "$log" ]] then command touch "$log" # for zsh :( fi printf "%b" "[$(date +'%Y-%m-%d %H:%M:%S')] $_command # under $environment\n" >> "${log}" if (( ${rvm_niceness:=0} > 0 )) then _command="nice -n $rvm_niceness $_command" fi ( rvm_ruby_string="$environment" __rvm_use eval "$_command" >> "${log}" 2>&1 ) result=$? if (( result > 0 )) then rvm_error "Error running '$command' under $env_name,\nplease read $log" fi return ${result:-0} } # Set shell options that RVM needs temporarily, these are reverted by __rvm_teardown. # see the top of ./scripts/initialize for settings that are needed all the time. # Setup must be always called after initialize, otherwise it does nothing ... except exporting. __rvm_setup() { # NOTE: the same set is located below - maker kjfdngkjd export rvm_head_flag rvm_ruby_selected_flag rvm_user_install_flag rvm_path_flag rvm_cron_flag rvm_static_flag rvm_default_flag rvm_loaded_flag rvm_llvm_flag rvm_skip_autoreconf_flag rvm_18_flag rvm_19_flag rvm_force_autoconf_flag rvm_autoconf_flags rvm_dump_environment_flag rvm_verbose_flag rvm_debug_flag rvm_trace_flag rvm_pretty_print_flag rvm_create_flag rvm_remove_flag rvm_gemdir_flag rvm_reload_flag rvm_auto_reload_flag rvm_ignore_gemsets_flag rvm_skip_gemsets_flag rvm_install_on_use_flag export rvm_gems_cache_path rvm_gems_path rvm_man_path rvm_ruby_gem_path rvm_ruby_log_path rvm_ruby_load_path rvm_gems_cache_path rvm_archives_path rvm_docs_path rvm_environments_path rvm_examples_path rvm_gems_path rvm_gemsets_path rvm_help_path rvm_hooks_path rvm_lib_path rvm_log_path rvm_patches_path rvm_repos_path rvm_rubies_path rvm_scripts_path rvm_src_path rvm_tmp_path rvm_user_path rvm_usr_path rvm_wrappers_path rvm_externals_path export rvm_ruby_strings rvm_ruby_binary rvm_ruby_gem_home rvm_ruby_home rvm_ruby_interpreter rvm_ruby_irbrc rvm_ruby_major_version rvm_ruby_minor_version rvm_ruby_package_name rvm_ruby_patch_level rvm_ruby_release_version rvm_ruby_repo_url rvm_ruby_repo_branch rvm_ruby_revision rvm_ruby_tag rvm_ruby_sha rvm_ruby_version rvm_ruby_require rvm_ruby_package_file rvm_ruby_name rvm_ruby_name rvm_ruby_args rvm_ruby_user_tag rvm_ruby_patch detected_rvm_ruby_name export __rvm_env_loaded next_token rvm_error_message rvm_gemset_name rvm_parse_break rvm_token rvm_action rvm_export_args rvm_gemset_separator rvm_expanding_aliases rvm_architectures rvm_patch_names rvm_tar_command rvm_tar_options rvm_ree_options rvm_patch_original_pwd rvm_project_rvmrc rvm_archive_extension rvm_autoinstall_bundler_flag rvm_codesign_identity rvm_expected_gemset_name rvm_without_gems # Setup only on first load. if (( __rvm_env_loaded != 1 )) then return 0 fi if [[ -n "${BASH_VERSION:-}" ]] && ! __function_on_stack cd pushd popd then trap 'status=$? ; __rvm_teardown_final ; set +x ; return $status' 0 1 2 3 15 fi if [[ -n "${ZSH_VERSION:-}" ]] then export rvm_zsh_clobber rvm_zsh_nomatch # Set clobber for zsh users, for compatibility with bash's append operator ( >> file ) behavior if setopt | GREP_OPTIONS="" \grep -s '^noclobber$' >/dev/null 2>&1 then rvm_zsh_clobber=0 else rvm_zsh_clobber=1 fi setopt clobber # Set no_nomatch so globs that don't match any files don't print out a warning if setopt | GREP_OPTIONS="" \grep -s '^nonomatch$' >/dev/null 2>&1 then rvm_zsh_nomatch=0 else rvm_zsh_nomatch=1 fi setopt no_nomatch fi } __rvm_teardown() { if builtin command -v __rvm_cleanup_tmp >/dev/null 2>&1 then __rvm_cleanup_tmp fi export __rvm_env_loaded # if __rvm_env_loaded is not set - detect it via rvm_tmp_path : __rvm_env_loaded:${__rvm_env_loaded:=${rvm_tmp_path:+1}}: : __rvm_env_loaded:${__rvm_env_loaded:=0}: # decrease load count counter : __rvm_env_loaded:$(( __rvm_env_loaded-=1 )): #skip teardown when already done or when not yet finished if [[ -z "${rvm_tmp_path:-}" ]] || (( __rvm_env_loaded > 0 )) then return 0 fi if [[ -n "${BASH_VERSION:-}" ]] then trap - 0 1 2 3 15 # Clear all traps, we do not want to go into an loop. fi if [[ -n "${ZSH_VERSION:-""}" ]] then # If rvm_zsh_clobber is 0 then "setopt" contained "noclobber" before rvm performed "setopt clobber". (( rvm_zsh_clobber == 0 )) && setopt noclobber # If rvm_zsh_nomatch is 0 then "setopt" contained "nonomatch" before rvm performed "setopt nonomatch". (( rvm_zsh_nomatch == 0 )) || setopt nomatch unset rvm_zsh_clobber rvm_zsh_nomatch fi if [[ -n "${rvm_stored_umask:-}" ]] then umask ${rvm_stored_umask} fi # TODO: create a cleanse array for this instead of the current hard coded # method. The array will be appended to whenever variables are used that # should be cleaned up when the current RVM commadn is done. # Cleanse and purge! (may be some redundancy here) # # NOTE: Removing rvm_bin_path here causes system wide installations to generate # a corrupt PATH, breaking the RVM installation. # # NOTE: the same set is located above - maker kjfdngkjd unset rvm_head_flag rvm_ruby_selected_flag rvm_user_install_flag rvm_path_flag rvm_cron_flag rvm_static_flag rvm_default_flag rvm_loaded_flag rvm_llvm_flag rvm_skip_autoreconf_flag rvm_18_flag rvm_19_flag rvm_force_autoconf_flag rvm_autoconf_flags rvm_dump_environment_flag rvm_verbose_flag rvm_debug_flag rvm_trace_flag rvm_pretty_print_flag rvm_create_flag rvm_remove_flag rvm_gemdir_flag rvm_reload_flag rvm_auto_reload_flag rvm_ignore_gemsets_flag rvm_skip_gemsets_flag rvm_install_on_use_flag unset rvm_gems_cache_path rvm_gems_path rvm_man_path rvm_ruby_gem_path rvm_ruby_log_path rvm_ruby_load_path rvm_gems_cache_path rvm_archives_path rvm_docs_path rvm_environments_path rvm_examples_path rvm_gems_path rvm_gemsets_path rvm_help_path rvm_hooks_path rvm_lib_path rvm_log_path rvm_patches_path rvm_repos_path rvm_rubies_path rvm_scripts_path rvm_src_path rvm_tmp_path rvm_user_path rvm_usr_path rvm_wrappers_path rvm_externals_path unset rvm_ruby_strings rvm_ruby_binary rvm_ruby_gem_home rvm_ruby_home rvm_ruby_interpreter rvm_ruby_irbrc rvm_ruby_major_version rvm_ruby_minor_version rvm_ruby_package_name rvm_ruby_patch_level rvm_ruby_release_version rvm_ruby_repo_url rvm_ruby_repo_branch rvm_ruby_revision rvm_ruby_tag rvm_ruby_sha rvm_ruby_version rvm_ruby_require rvm_ruby_package_file rvm_ruby_name rvm_ruby_name rvm_ruby_args rvm_ruby_user_tag rvm_ruby_patch detected_rvm_ruby_name unset __rvm_env_loaded next_token rvm_error_message rvm_gemset_name rvm_parse_break rvm_token rvm_action rvm_export_args rvm_gemset_separator rvm_expanding_aliases rvm_architectures rvm_patch_names rvm_tar_command rvm_tar_options rvm_ree_options rvm_patch_original_pwd rvm_project_rvmrc rvm_archive_extension rvm_autoinstall_bundler_flag rvm_codesign_identity rvm_expected_gemset_name rvm_without_gems if builtin command -v __rvm_cleanup_download >/dev/null 2>&1 then __rvm_cleanup_download fi return 0 } __rvm_teardown_final() { __rvm_env_loaded=1 unset __rvm_project_rvmrc_lock __rvm_teardown } __rvm_do_with_env_before() { if [[ -n "${rvm_scripts_path:-}" || -n "${rvm_path:-}" ]] then # Load env - setup all required variables, __rvm_teardown is called on the end source "${rvm_scripts_path:-"$rvm_path/scripts"}/initialize" __rvm_setup fi } __rvm_do_with_env_after() { __rvm_teardown } __rvm_do_with_env() { typeset result __rvm_do_with_env_before "$@" result=$? __rvm_do_with_env_after return ${result:-0} } __rvm_conditionally_do_with_env() { if (( __rvm_env_loaded > 0 )) then "$@" else __rvm_do_with_env "$@" fi } __rvm_ensure_is_a_function() { if [[ ${rvm_reload_flag:=0} == 1 ]] || ! is_a_function rvm then for script in version selector selector_gemsets cd cli override_gem do if [[ -f "$rvm_scripts_path/$script" ]] then source "$rvm_scripts_path/$script" else printf "%b" \ "WARNING: Could not source '$rvm_scripts_path/$script' as file does not exist. RVM will likely not work as expected.\n" fi done fi } 1.18.61.19. cleanup #!/usr/bin/env bash # # rm -rf with *some* safeguards in place. # __rvm_rm_rf() { typeset result target result=1 target="${1%%+(/|.)}" #NOTE: RVM Requires extended globbing shell feature turned on. if [[ -n "${ZSH_VERSION:-}" ]] then setopt extendedglob else if [[ -n "${BASH_VERSION:-}" ]] then shopt -s extglob # Extended globs else printf "%b" "What the heck kind of shell are you running here???\n" fi fi case "${target}" in (*(/|.)@(|/Applications|/Developer|/Guides|/Information|/Library|/Network|/System|/User|/Users|/Volumes|/backups|/bdsm|/bin| /boot|/cores|/data|/dev|/etc|/home|/lib|/lib64|/mach_kernel|/media|/misc|/mnt|/net|/opt|/private|/proc|/root|/sbin|/selinux| /srv|/sys|/tmp|/usr|/var)) false ;; (*) if [[ -n "${target}" ]] then if [[ -d "${target}" ]] then # Directory \rm -rf "${target}" result=0 elif [[ -f "${target}" || -L "${target}" ]] then # File / Symbolic Link \rm -f "${target}" result=0 else result=0 # already gone!? fi fi ;; esac return $result } __rvm_reboot() { rvm_warn "Do you wish to reboot rvm?\n('yes', or 'no')> " typeset response response="no" read response if [[ "yes" == "$response" ]] then builtin cd $rvm_path command -v __rvm_reset >> /dev/null 2>&1 || \ source "$rvm_scripts_path/functions/reset" __rvm_reset mv "$rvm_archives_path" "$HOME/.archives" if [[ "/" == "$rvm_path" ]] then rvm_error "remove '/' ?!... NO!" else if [[ -d "$rvm_path" ]] then __rvm_rm_rf "$rvm_path" fi fi gem install rvm $rvm_gem_options "$rvm_scripts_path/get" latest source "$rvm_scripts_path/rvm" else rvm_log "Carry on then..." fi return 0 } # Cleans up temp folders for a given prefix ($1), # or the current process id. __rvm_cleanup_tmp() { if [[ -d "${rvm_tmp_path}/" ]] then case "${rvm_tmp_path%\/}" in *tmp) __rvm_rm_rf "${rvm_tmp_path}/${1:-$$}*" ;; esac fi return 0 } 1.18.61.20. installer #!/usr/bin/env bash #Handle Solaris Hosts if [[ "$(uname -s)" == "SunOS" ]] then export PATH PATH="/usr/gnu/bin:$PATH" fi if [[ -n "${rvm_user_path_prefix:-}" ]] then PATH="${rvm_user_path_prefix}:$PATH" fi install_setup() { set -o errtrace export HOME="${HOME%%+(\/)}" # Remove trailing slashes if they exist on HOME case "$MACHTYPE" in *aix*) name_opt=-name ;; *) name_opt=-iname ;; esac if (( ${rvm_ignore_rvmrc:=0} == 0 )) then : rvm_stored_umask:${rvm_stored_umask:=$(umask)} rvm_rvmrc_files=("/etc/rvmrc" "$HOME/.rvmrc") if [[ -n "${rvm_prefix:-}" ]] && ! [[ "$HOME/.rvmrc" -ef "${rvm_prefix}/.rvmrc" ]] then rvm_rvmrc_files+=( "${rvm_prefix}/.rvmrc" ) fi for file in "${rvm_rvmrc_files[@]}" do if [[ -s "$file" ]] then . $file fi done unset rvm_rvmrc_files fi export PS4 PATH PS4="+ \${BASH_SOURCE##\${rvm_path:-}} : \${FUNCNAME[0]:+\${FUNCNAME[0]}()} if [[ -n "${rvm_user_path_prefix:-}" ]] then PATH="${rvm_user_path_prefix}:$PATH" fi # TODO: Figure out a much better name for 'rvm_user_install_flag' # mpapis: self contained was a quite good name if (( UID == 0 )) || [[ -n "${rvm_prefix:-}" && "${rvm_prefix:-}" != "${HOME}" ]] then true "${rvm_user_install_flag:=0}" else true "${rvm_user_install_flag:=1}" fi export rvm_user_install_flag unset rvm_auto_flag } install_usage() { printf "%b" " Usage: ${0} [options] options: --auto : Automatically update shell profile files. --path : Installation directory (rvm_path). --help : Display help/usage (this) message --version : display rvm package version " } display_thank_you() { printf "%b" " # ${name:-"${USER:-$(id | sed -e 's/^[^(]*(//' -e 's/).*$//')}"}, \${LINENO} > " # # Thank you for using RVM! # I sincerely hope that RVM helps to make your life easier and more enjoyable!!! # # ~Wayne " } determine_install_path() { export HOME="${HOME%%+(\/)}" # Remove trailing slashes if they exist on HOME if [[ -z "${rvm_path:-}" ]] then if (( UID == 0 )) then rvm_path="/usr/local/rvm" else rvm_path="${HOME}/.rvm" fi fi export rvm_path } determine_install_or_upgrade() { export upgrade_flag if [[ -d "$rvm_path" && -s "${rvm_path}/scripts/rvm" ]] then upgrade_flag=1 else upgrade_flag=0 fi } print_install_header() { if [[ ${upgrade_flag:-0} -eq 1 ]] then printf "%b" "\nUpgrading the RVM installation in $rvm_path/\n" else printf "%b" "\nInstalling RVM to $rvm_path/\n" fi } configure_installation() { typeset save_rvm_without_gems install_source_path="$(dirname "$0" | sed 's#\/scripts$##')" if [[ -d "$install_source_path/scripts" \ && -s "$install_source_path/scripts/functions/utility" ]] then builtin cd "$install_source_path" fi # Save scripts path scripts_path=${rvm_scripts_path:-""} rvm_scripts_path="${PWD%%+(\/)}/scripts" save_rvm_without_gems="${rvm_without_gems:-}" # Load scripts. source "$PWD/scripts/initialize" source "$PWD/scripts/functions/init" source "$PWD/scripts/version" __rvm_initialize # Restore Scripts Path rvm_scripts_path=${scripts_path:-"$rvm_path/scripts"} rvm_without_gems="${save_rvm_without_gems:-${rvm_without_gems}}" item="* " question="\n<?>" cwd="${PWD%%+(\/)}" true "${source_path:=$cwd}" return 0 } create_install_paths() { install_paths=( archives src log bin gems man rubies config user tmp gems environments wrappers ) for install_path in "${install_paths[@]}" do if [[ ! -d "$rvm_path/$install_path" ]] then mkdir -p "$rvm_path/$install_path" fi done if [[ "$rvm_bin_path" != "" ]] then if [[ ! -d "$rvm_bin_path" ]] then mkdir -p "$rvm_bin_path" fi fi return 0 } cleanse_old_entities() { # # Remove old files that no longer exist. # for script in utility array ; do if [[ -f "$rvm_path/scripts/${script}" ]] then rm -f "$rvm_path/scripts/${script}" fi done return 0 } install_rvm_files() { files=(README LICENCE VERSION) for file in "${files[@]}" do cp -f "$source_path/${file}" "$rvm_path/${file}" done directories=(config contrib scripts examples lib help patches) for directory in ${directories[@]} do for entry in $(find $directory 2>/dev/null) do if [[ -f "$source_path/$entry" ]] then # Target is supposed to be a file, remove if it is a directory. if [[ -d "$rvm_path/$entry" ]] then __rvm_rm_rf "$rvm_path/$entry" fi cp -f "$source_path/$entry" "$rvm_path/$entry" elif [[ -d "$source_path/$entry" ]] then # Target is supposed to be a directory, remove if it is a file. if [[ -f "$rvm_path/$entry" ]] then rm -f "$rvm_path/$entry" fi if [[ ! -d "$rvm_path/$entry" ]] then mkdir -p "$rvm_path/$entry" fi fi done done return 0 } install_rvm_hooks() { typeset hook_x_flag entry for entry in $(find hooks 2>/dev/null) do if [[ -f "$source_path/$entry" ]] then # Target is supposed to be a file, remove if it is a directory. if [[ -d "$rvm_path/$entry" ]] then __rvm_rm_rf "$rvm_path/$entry" fi # Source is first level hook (after_use) and target is custom user hook, preserve it if echo "$entry" | GREP_OPTIONS="" \grep -E '^hooks/[[:alpha:]]+_[[:alpha:]]+$' >/dev/null && [[ -f "$rvm_path/$entry" ]] && ! GREP_OPTIONS="" \grep "$(basename ${entry})_\*" "$rvm_path/$entry" >/dev/null then mv -f "$rvm_path/$entry" "$rvm_path/${entry}_custom" fi if [[ -x "$rvm_path/$entry" ]] then hook_x_flag=$? else hook_x_flag=$? fi cp -f "$source_path/$entry" "$rvm_path/$entry" if (( hook_x_flag == 0 )) then [[ -x "$rvm_path/$entry" ]] || chmod +x "$rvm_path/$entry" fi elif [[ -d "$source_path/$entry" ]] then # Target is supposed to be a directory, remove if it is a file. if [[ -f "$rvm_path/$entry" ]] then rm -f "$rvm_path/$entry" fi if [[ ! -d "$rvm_path/$entry" ]] then mkdir -p "$rvm_path/$entry" fi fi done #fix broken copy of after_use to after_use_custom if [[ -f "$rvm_path/hooks/after_use_custom" ]] && GREP_OPTIONS="" \grep "after_use_\*" "$rvm_path/hooks/after_use_custom" >/dev/null then rm -f "$rvm_path/hooks/after_use_custom" fi return 0 } setup_configuration_files() { pushd "$rvm_path" >/dev/null if [[ -f config/user ]] then mv config/user user/db fi if [[ -f config/installs ]] then mv config/installs user/installs fi if [[ ! -s user/db ]] then echo '# User settings, overrides db settings and persists across installs.' \ >> user/db fi if [[ -s config/rvmrcs ]] then mv config/rvmrcs user/rvmrcs else if [[ ! -f user/rvmrcs ]] then touch user/rvmrcs fi fi if [[ ! -f user/md5 ]] then touch user/md5 fi # Prune old (keyed-by-hash) trust entries GREP_OPTIONS="" \grep '^_' user/rvmrcs > user/rvmrcs.new || true mv user/rvmrcs.new user/rvmrcs popd >/dev/null } ensure_scripts_are_executable() { scripts=(monitor match log install db fetch log set package) for script_name in "${scripts[@]}" do if [[ -s "$rvm_scripts_path/$script_name" && ! -x "$rvm_scripts_path/$script_name" ]] then chmod +x "$rvm_scripts_path/$script_name" fi done return 0 } install_binscripts() { typeset -a files typeset system_bin files=(rvm-prompt rvm-installer rvm rvmsudo rvm-shell rvm-smile rvm-exec rvm-auto-ruby) [[ -d "${rvm_bin_path}" ]] || mkdir -p "${rvm_bin_path}" for file in "${files[@]}" do # Ensure binscripts are always available in rvm_path/bin first. [[ -f "${rvm_bin_path}/${file}" ]] && rm -f "${rvm_bin_path}/${file}" cp -f "${source_path}/binscripts/${file}" "${rvm_bin_path}/${file}" [[ -x "${rvm_bin_path}/${file}" ]] || chmod +x "${rvm_bin_path}/${file}" # try to clean old installer files left in usual places added to PATH for system_bin in ~/bin /usr/local/bin do if [[ "${system_bin}" != "${rvm_bin_path}" && -x "${system_bin}/${file}" ]] then rm -f "${system_bin}/${file}" 2>/dev/null || printf "!!! could not remove ${system_bin}/${file}, remove it manually with: !!! > sudo rm -f ${system_bin}/${file} " fi done done # optional binscripts for file in rake bundle do [[ -f "${rvm_bin_path}/${file}" ]] || cp -f "${source_path}/binscripts/${file}" "${rvm_bin_path}/${file}" done return 0 } install_gemsets() { typeset gemset_files if [[ ${rvm_keep_gemset_defaults_flag:-0} == 0 && -d "$rvm_path/gemsets" ]] then rm -rf "$rvm_path/gemsets" fi if [[ -d gemsets/ ]] then [[ -d "$rvm_path/gemsets" ]] || mkdir -p "$rvm_path/gemsets" gemset_files=($( find "${PWD%%+(\/)}/gemsets" "${name_opt}" '*.gems' | sed 's/^\.\///' )) for gemset_file in "${gemset_files[@]}" do cwd="${PWD//\//\\/}\/gemsets\/" destination="$rvm_path/gemsets/${gemset_file/$cwd}" if [[ ! -s "$destination" ]] then destination_path="${destination%/*}" [[ -d "$destination_path" ]] || mkdir -p "$destination_path" if [[ -n "${rvm_without_gems:-}" ]] then sed -E '/^('"${rvm_without_gems// /|}"')/ d' < "$gemset_file" > "$destination" else cp "$gemset_file" "$destination" fi fi done fi if [[ -n "${rvm_without_gems:-}" ]] then if GREP_OPTIONS="" \grep "rvm_without_gems=" ~/.rvmrc >/dev/null then sed -i 's/^rvm_without_gems=.*$/rvm_without_gems="'"${rvm_without_gems}"'"/' ~/.rvmrc else echo "rvm_without_gems=\"${rvm_without_gems}\"" >> ~/.rvmrc fi fi } update_gemsets_install_rvm() { typeset paths path installed found missing typeset -a missing if [[ ${rvm_keep_gemset_defaults_flag:-0} == 0 ]] && ! [[ " ${rvm_without_gems:-} " =~ " rvm " ]] then # rvm /gems paths=($( find "$rvm_path/gems" -maxdepth 1 "${name_opt}" '*@global' | sed 's/^\.\///' )) for path in "${paths[@]}" do # skip unless this ruby is installed installed="${path%@global}" installed="${installed/\/gems\//\/rubies\//}/bin/ruby" installed=${installed//\\/} [[ -x "$installed" ]] || continue # rvm /gems @global /gems found=($( find "${path%%+(\/)}/gems" -maxdepth 1 "${name_opt}" 'rvm-*' | sed 's/^\.\///' )) (( ${#found[@]} > 0 )) || missing+=( "$path" ) done if (( ${#missing[@]} > 0 )) then printf " Installing rvm gem in ${#missing[@]} gemsets " for path in "${missing[@]}" do rvm "${path##*/}" do gem install rvm | awk '{printf "."}' done printf "\n" fi fi } install_patchsets() { if [[ ${rvm_keep_patchsets_flag:-0} == 0 && -d "$rvm_path/patchsets" ]] then rm -rf "$rvm_path/patchsets" fi if [[ -d patchsets/ ]] then [[ -d "$rvm_path/patchsets" ]] || mkdir -p "$rvm_path/patchsets" patchsets=($( builtin cd patchsets find \. -type f "${name_opt}" '*' | sed 's/^\.\///' )) for patchset_file in "${patchsets[@]}" do destination="$rvm_path/patchsets/$patchset_file" if [[ ! -s "$destination" || "${patchset_file##*/}" == "default" ]] then destination_path="${destination%/*}" [[ -d "$destination_path" ]] || mkdir -p "$destination_path" [[ -f "$destination" ]] && rm -f "$destination" cp "patchsets/$patchset_file" "$destination" fi done fi } cleanse_old_environments() { if [[ -d "$rvm_path/environments" ]] then # Remove BUNDLE_PATH from environment files environments=($( find "$rvm_path/environments/" -maxdepth 1 -mindepth 1 -type f )) if (( ${#environments[@]} > 0 )) then for file in "${environments[@]}" do if GREP_OPTIONS="" \grep 'BUNDLE_PATH' "$file" > /dev/null 2>&1 then GREP_OPTIONS="" \grep -v 'BUNDLE_PATH' "$file" > "$file.new" mv "$file.new" "$file" fi done fi fi } migrate_old_gemsets() { for gemset in "$rvm_path"/gems/*\%* do new_path=${gemset/\%/${rvm_gemset_separator:-"@"}} if [[ -d "$gemset" ]] && [[ ! -d "$new_path" ]] then printf "%b" "\n Renaming $(basename "$gemset") to $(basename "$new_path") for new gemset separator." mv "$gemset" "$new_path" fi done for gemset in "$rvm_path"/gems/*\+* do new_path=${gemset/\+/${rvm_gemset_separator:-"@"}} if [[ -d "$gemset" && ! -d "$new_path" ]] then printf "%b" "\n Renaming $(basename "$gemset") to $(basename "$new_path") for new gemset separator." mv $gemset $new_path fi done for gemset in "$rvm_path"/gems/*\@ do new_path=$(echo $gemset | sed -e 's#\@$##') if [[ -d "$gemset" && ! -d "$new_path" ]] then printf "%b" "\n Fixing: $(basename "$gemset") to $(basename "$new_path") for new gemset separator." mv "$gemset" "$new_path" fi done } migrate_defaults() { # Move from legacy defaults to the new, alias based system. if [[ -s "$rvm_path/config/default" ]] then original_version="$(basename "$(GREP_OPTIONS="" \grep GEM_HOME "$rvm_path/config/default" \ | awk -F"'" '{print $2}' | sed "s#\%#${rvm_gemset_separator:-"@"}#")")" if [[ -n "$original_version" ]] then "$rvm_scripts_path/alias" create default "$original_version" &> /dev/null fi unset original_version __rvm_rm_rf "$rvm_path/config/default" fi } correct_binary_permissions() { typeset -a files mkdir -p "${rvm_bin_path}" files=(rvm rvmsudo rvm-shell rvm-auto-ruby) for file in "${files[@]}" do if [[ -s "${rvm_bin_path}/${file}" && ! -x "${rvm_bin_path}/${file}" ]] then chmod +x "${rvm_bin_path}/${file}" fi done files=( manage alias cleanup current db disk-usage docs env fetch gemsets get hash help hook info install list maglev match md5 migrate monitor notes override_gem package patchsets repair rtfm rubygems rvm selector selector_gemsets set snapshot tools upgrade wrapper ) for file in "${files[@]}" do if [[ -s "${rvm_scripts_path}/${file}" && ! -x "${rvm_scripts_path}/${file}" ]] then chmod +x "${rvm_scripts_path}/${file}" fi done } install_man_pages() { files=($( builtin cd "$install_source_path/man" find . -maxdepth 2 -mindepth 1 -type f -print )) for file in "${files[@]//.\/}" do if [[ ! -d $rvm_man_path/${file%\/*} ]] then mkdir -p $rvm_man_path/${file%\/*} fi cp -Rf "$install_source_path/man/$file" "$rvm_man_path/$file" || \ printf "%b" " Please run the installer using rvmsudo to fix file permissions " chown :$rvm_group_name "$rvm_man_path/$file" done } cleanup_tmp_files() { files=($( find "$rvm_path/" -mindepth 1 -maxdepth 2 "${name_opt}" '*.swp' -type f )) if (( ${#files[@]} > 0 )) then printf "%b" "\n Cleanup any .swp files." for file in "${files[@]}" do if [[ -f "$file" ]] then rm -f "$file" fi done fi } display_notes() { true ${upgrade_flag:=0} typeset itype profile_file if (( upgrade_flag == 0 )) then itype=Installation else itype=Upgrade fi if builtin command -v git > /dev/null 2>&1 then name="$(git config user.name 2>/dev/null || echo ${SUDO_USER:-${USERNAME}} )" fi [[ -x ./scripts/notes ]] || chmod +x ./scripts/notes if (( upgrade_flag == 0 )) then ./scripts/notes initial else ./scripts/notes upgrade fi if (( upgrade_flag == 0 )) then profile_file="${user_profile_file:-${etc_profile_file:-$rvm_path/scripts/rvm}}" printf "%b" "$itype of RVM in $rvm_path/ is almost complete: " if (( ${rvm_user_install_flag:=0} == 0 )) then printf "%b" " * First you need to add all users that will be using rvm to '${rvm_group_name}' group, and logout - login again, anyone using rvm will be operating with \`umask g+w\`. " fi printf "%b" " * To start using RVM you need to run \`source ${profile_file}\` in all your open shell windows, in rare cases you need to reopen all shell windows. " else printf "%b" "$itype of RVM in $rvm_path/ is complete. " fi } # # root install functions. # setup_rvm_path_permissions() { chown -R root:"$rvm_group_name" "$rvm_path" chmod -R g+w "$rvm_path" if [[ -d "$rvm_path" ]] then find "$rvm_path" -type d -print0 | xargs -n1 -0 chmod g+s fi return 0 } setup_rvm_group() { typeset __group_params __group_params="" if [[ -n "${rvm_group_id}" ]] then __group_params="${__group_params} -g ${rvm_group_id}" fi if [[ -n "$ZSH_VERSION" ]] then __group_params=( ${=__group_params} ) else __group_params=( ${__group_params} ) fi if GREP_OPTIONS="" \grep "$rvm_group_name" /etc/group >/dev/null 2>&1 then echo " RVM system user group '$rvm_group_name' exists, proceeding with installation." else echo " Creating RVM system user group '$rvm_group_name'" case "$(uname)" in "OpenBSD") groupadd ${__group_params[@]} "$rvm_group_name" ;; "FreeBSD") pw groupadd ${__group_params[@]} "$rvm_group_name" -q ;; "Linux") if [[ -f "/etc/SuSE-release" ]] then groupadd ${__group_params[@]} "$rvm_group_name" else groupadd -f ${__group_params[@]} "$rvm_group_name" fi ;; "Darwin") if ! dscl . -read "/Groups/$rvm_group_name" 1>/dev/null 2>&1 then if [[ -n "${rvm_group_id}" ]] then __group_params="${rvm_group_id}" else __group_params="501" #only gids > 500 show up in user preferences #Find an open gid while true do name=$(dscl . search /groups PrimaryGroupID ${__group_params} | cut -f1 -s) if [[ -z "$name" ]] then break fi __group_params=$(( __group_params + 1 )) done fi # Create the group, isn't OSX "fun"?! :) # Thanks for the assist frogor of ##osx-server on freenode! Appreciate the assist! dscl . -create "/Groups/$rvm_group_name" gid "${__group_params}" fi ;; "SunOS") groupadd ${__group_params[@]} "$rvm_group_name" ;; esac fi return 0 } system_check() { typeset os os=$(uname) case "$os" in OpenBSD|Linux|FreeBSD|Darwin|SunOS) return 0 # Accounted for, continue. ;; *) printf "%b" "Installing RVM as root is currently only supported on the following known OS's (uname):\n FreeBSD, OpenBSD, Darwin and SunOS\nWhereas your OS is reported as '$os'" >&2 return 1 ;; esac } setup_etc_profile() { export etc_profile_file if (( ${rvm_etc_profile_flag:-1} == 0 )) then return 0 ; fi # opt-out typeset executable add_to_profile_flag zshrc_file executable=0 add_to_profile_flag=0 etc_profile_file="/etc/profile.d/rvm.sh" if [[ -d /etc/profile.d ]] then executable=1 else mkdir -p /etc/profile.d add_to_profile_flag=1 executable=0 fi if ! [[ -s "${etc_profile_file}" ]] || (( ${rvm_auto_flag:-0} == 1 )) then printf "%b" "# # RVM profile # # /etc/profile.d/rvm.sh # sh extension required for loading. # if [ -n \"\${BASH_VERSION:-}\" -o -n \"\${ZSH_VERSION:-}\" ] && test \"\`ps -p \$\$ -o comm=\`\" != dash && test \"\`ps -p \$\$ -o comm=\`\" != sh then : rvm_stored_umask:\${rvm_stored_umask:=\$(umask)} # Load user rvmrc configurations, if exist for file in \"/etc/rvmrc\" \"\$HOME/.rvmrc\" ; do [[ -s \"\$file\" ]] && source \$file done if [[ -n \"\${rvm_prefix:-}\" ]] && ! [[ \"\$HOME/.rvmrc\" -ef \"\${rvm_prefix}/.rvmrc\" ]] && [[ -s \"\${rvm_prefix}/.rvmrc\" ]] then source \"\${rvm_prefix}/.rvmrc\" fi # Load RVM if it is installed, try user then root install. if [[ -s \"\$rvm_path/scripts/rvm\" ]] ; then source \"\$rvm_path/scripts/rvm\" elif [[ -s \"\$HOME/.rvm/scripts/rvm\" ]] ; then Linux, true \${rvm_path:=\"\$HOME/.rvm\"} source \"\$HOME/.rvm/scripts/rvm\" elif [[ -s \"/usr/local/rvm/scripts/rvm\" ]] ; then true \${rvm_path:=\"/usr/local/rvm\"} source \"/usr/local/rvm/scripts/rvm\" fi # # Opt-in for custom prompt through by setting: # # rvm_ps1=1 # # in either /etc/rvmrc or \$HOME/.rvmrc # if [[ \${rvm_ps1:-0} -eq 1 ]] ; then # Source RVM ps1 functions for a great prompt. if [[ -s \"\$rvm_path/contrib/ps1_functions\" ]] ; then source \"\$rvm_path/contrib/ps1_functions\" elif [[ -s \"/usr/local/rvm/contrib/ps1_functions\" ]] ; then source \"/usr/local/rvm/contrib/ps1_functions\" fi if command -v ps1_set >/dev/null 2>&1 ; then ps1_set fi fi # Add \$rvm_bin_path to \$PATH if necessary if [[ \"\${rvm_bin_path}\" != \"\${rvm_path}/bin\" ]] ; then regex=\"^([^:]*:)*\${rvm_bin_path}(:[^:]*)*\$\" if [[ ! \"\${PATH}\" =~ \$regex ]] ; then __rvm_add_to_path prepend \"\${rvm_bin_path}\" fi fi fi " > "${etc_profile_file}" if (( executable )) && [[ ! -x "${etc_profile_file}" ]] then chmod +x "${etc_profile_file}" fi if (( add_to_profile_flag )) && ! GREP_OPTIONS="" \grep "source ${etc_profile_file}" /etc/profile >/dev/null 2>&1 then printf "%b" "\nsource ${etc_profile_file}\n" >> /etc/profile fi for zshrc_file in $( find /etc/ -name zprofile -type f 2>/dev/null ; find /etc/ -name zlogin -type f 2>/dev/null ; true ) /etc/zprofile do if [[ ! -f "${zshrc_file}" ]] then printf "%b" "\nsource ${etc_profile_file}\n" > $zshrc_file elif ! GREP_OPTIONS="" \grep "source /etc/bash" "${zshrc_file}" && ! GREP_OPTIONS="" \grep "source /etc/profile" "${zshrc_file}" then printf "%b" "\nsource ${etc_profile_file}\n" >> $zshrc_file fi break # process only first file found done fi return 0 } setup_rvmrc() { if (( UID == 0 )) then rvmrc_file="/etc/rvmrc" if ! GREP_OPTIONS="" \grep 'umask g+w' $rvmrc_file >/dev/null 2>&1 then echo 'umask g+w' >> $rvmrc_file fi if [[ -s $rvmrc_file ]] then chown $USER:${rvm_group_name:-$USER} $rvmrc_file fi else rvmrc_file="$HOME/.rvmrc" fi return 0 } setup_user_profile() { (( UID > 0 )) || return 0 export user_profile_file export -a user_login_files user_rc_files typeset -a search_list target_rc target_login found_rc found_login typeset etc_profile_file profile_file etc_profile_file="/etc/profile.d/rvm.sh" search_list=( ~/.profile ~/.bashrc ~/.bash_profile ~/.bash_login ~/.zshenv ~/.zprofile ~/.zshrc ~/.zlogin ) target_rc=( ~/.bashrc ) [[ -f ~/.zshenv ]] && target_rc+=( ~/.zshenv ) || target_rc+=( ~/.zshrc ) [[ -f ~/.bash_profile ]] && target_login+=( ~/.bash_profile ) || target_login+=( ~/.bash_login ) [[ -f ~/.zprofile ]] && target_login+=( ~/.zprofile ) || target_login+=( ~/.zlogin ) for profile_file in ${search_list[@]} do [[ -f $profile_file ]] && GREP_OPTIONS="" \grep PATH=.*\$HOME/.rvm/bin $profile_file >/dev/null && found_rc+=( $profile_file ) || true [[ -f $profile_file ]] && { { GREP_OPTIONS="" \grep \..*scripts/rvm $profile_file >/dev/null && found_login+=( $profile_file ) } || { GREP_OPTIONS="" \grep source.*scripts/rvm $profile_file >/dev/null && found_login+=( $profile_file ) } } || true done if (( rvm_auto_flag == 1 && ${#found_rc[@]} > 0 )) then printf "%b" " Removing rvm PATH line from ${found_rc[*]}.\n" for profile_file in ${found_rc[@]} do sed -i"" -e '/PATH=.*\$HOME\/.rvm\/bin/ d;' ${profile_file} # also delete duplicate blank lines sed -i"" -e '/^\s*$/{ N; /^\n$/ D; };' ${profile_file} done found_rc=() fi if (( rvm_auto_flag == 1 || ${#found_rc[@]} == 0 )) then printf "%b" " Adding rvm PATH line to ${target_rc[*]}.\n" for profile_file in ${target_rc[@]} do touch $profile_file printf "%b" " PATH=\$PATH:\$HOME/.rvm/bin # Add RVM to PATH for scripting " >> $profile_file done user_rc_files=( ${target_rc[@]} ) else printf "%b" " RVM PATH line found in ${found_rc[*]}.\n" user_rc_files=( ${found_rc[@]} ) fi if (( rvm_auto_flag == 1 && ${#found_login[@]} > 0 )) then printf "%b" " Removing rvm loading line from ${found_login[*]}.\n" for profile_file in ${found_login[@]} do sed -i"" -e '/source.*scripts\/rvm/ d; /\. .*scripts\/rvm/ d;' ${profile_file} # also delete duplicate blank lines sed -i"" -e '/^\s*$/{ N; /^\n$/ D; };' ${profile_file} done found_rc=() fi if (( rvm_auto_flag == 1 || ${#found_login[@]} == 0 )) then printf "%b" " Adding rvm loading line to ${target_login[*]}.\n" for profile_file in ${target_login[@]} do touch $profile_file printf "%b" " [[ -s \"\$HOME/.rvm/scripts/rvm\" ]] && source \"\$HOME/.rvm/scripts/rvm\" # Load RVM into a shell session *as a function* " >> $profile_file done user_login_files=( ${target_login[@]} ) else printf "%b" " RVM sourcing line found in ${found_login[*]}.\n" user_login_files=( ${found_login[@]} ) fi return 0 } root_canal() { true ${rvm_group_name:=rvm} if (( UID == 0 )) && system_check then setup_rvm_group setup_etc_profile setup_rvm_path_permissions fi return 0 } record_ruby_configs() { source "$PWD/scripts/functions/manage/base" __rvm_record_ruby_configs } record_installation_time() { date +%s > $rvm_path/installed.at if (( UID == 0 )) && system_check then # fix the rights explicitly as this is the last action chmod g+w "$rvm_path/installed.at" fi return 0 } 1.18.61.21. fun #!/usr/bin/env bash __rvm_Answer_to_the_Ultimate_Question_of_Life_the_Universe_and_Everything() { for index in {1..750} ; do sleep 0.25 ; echo -n '.' ; done ; printf "%d" 0x2A echo return 0 } __rvm_ultimate_question() { printf "%b" " I do not know the Ultimate Question, however I can help you build a more powerful Ruby which can compute the Ultimate Question: $ rvm install rbx " return 0 } 1.18.61.22. gemset #!/usr/bin/env bash __rvm_current_gemset() { # Fetch the current gemset via GEM_HOME typeset current_gemset current_gemset="${GEM_HOME:-}" # We only care about the stuff to the right of the separator. current_gemset="${current_gemset##*${rvm_gemset_separator:-@}}" if [[ "${current_gemset}" == "${GEM_HOME:-}" ]] ; then echo '' else echo "${current_gemset}" fi } __rvm_using_gemset_globalcache() { "$rvm_scripts_path/db" "$rvm_user_path/db" \ "use_gemset_globalcache" | GREP_OPTIONS="" \grep '^true$' >/dev/null 2>&1 return $? } __rvm_current_gemcache_dir() { if __rvm_using_gemset_globalcache; then echo "$rvm_gems_cache_path" else echo "${rvm_ruby_gem_home:-"$GEM_HOME"}/cache" fi return 0 } 1.18.61.23. hooks 1.18.61.23.1. jruby #!/usr/bin/env bash export JRUBY_OPTS jruby_ngserver_is_running() { ps auxww | GREP_OPTIONS="" \grep '[c]om.martiansoftware.nailgun.NGServer' >/dev/null } jruby_ngserver_start() { if ! jruby_ngserver_is_running then (JRUBY_OPTS='' jruby --ng-server 2>&1 1>/dev/null)& fi } jruby_options_trim() { JRUBY_OPTS="${JRUBY_OPTS## }" JRUBY_OPTS="${JRUBY_OPTS%% }" } jruby_options_append() { for param in "$@" do if ! [[ " ${JRUBY_OPTS} " =~ " $param " ]] then JRUBY_OPTS="${JRUBY_OPTS} $param" fi done jruby_options_trim } jruby_options_remove() { JRUBY_OPTS=" ${JRUBY_OPTS} " for param in "$@" do if [[ "${JRUBY_OPTS}" =~ " $param " ]] then JRUBY_OPTS="${JRUBY_OPTS// $param / }" fi done jruby_options_trim } jruby_clean_project_options() { if [[ -n "${PROJECT_JRUBY_OPTS}" ]] then unset PROJECT_JRUBY_OPTS fi } 1.18.61.24. manage 1.18.61.24.1. goruby #!/usr/bin/env bash goruby_install() { unset GEM_HOME GEM_PATH MY_RUBY_HOME IRBRC export PATH __rvm_remove_rvm_from_path __rvm_conditionally_add_bin_path builtin hash -r rvm_ruby_home="$rvm_rubies_path/$rvm_ruby_interpreter" __rvm_fetch_from_github "ruby" "trunk" __rvm_apply_patches ; result=$? if (( result > 0 )) then rvm_error "There has been an error while trying to apply patches to goruby. exit $result fi \nHalting the installation." #builtin cd "${rvm_src_path}/$rvm_ruby_string/configure" if [[ ! -s "${rvm_src_path}/$rvm_ruby_string/configure" ]] then if builtin command -v autoreconf &> /dev/null then __rvm_run "autoreconf" "autoreconf" "Running autoreconf" else rvm_error "rvm expects autoreconf to install this ruby interpreter, autoreconf was not found in PATH. \ \nHalting installation." exit $result fi fi if [[ -s ./Makefile && -z "$rvm_reconfigure_flag" ]] then if (( ${rvm_debug_flag:=0} > 0 )) then rvm_debug "Skipping configure step, Makefile exists so configure must have already been run." fi elif [[ -n "$rvm_ruby_configure" ]] then __rvm_run "configure" "$rvm_ruby_configure" result=$? if (( result > 0 )) then rvm_error "There has been an error while trying to configure the source. exit $result fi \nHalting the installation." elif [[ -s ./configure ]] then typeset configure_command configure_command="${rvm_configure_env:-""} ./configure --prefix=$rvm_ruby_home $rvm_configure_flags" __rvm_run "configure" "$configure_command" \ "Configuring $rvm_ruby_string using $rvm_configure_flags, this may take a while depending on your cpu(s)..." result=$? if (( result > 0 )) then rvm_error "There has been an error while trying to configure the source. exit $result fi \nHalting the installation." else rvm_error "Skipping configure step, 'configure' script does not exist, did autoreconf not run successfully?" fi rvm_ruby_make=${rvm_ruby_make:-"make"} __rvm_run "make" "$rvm_ruby_make golf $rvm_make_flags" \ "Compiling $rvm_ruby_string, this may take a while depending on your cpu(s)..." result=$? if (( result > 0 )) then rvm_error "There has been an error while trying to run make. exit $result fi \nHalting the installation." rvm_ruby_make_install=${rvm_ruby_make_install:-"make install"} __rvm_run "install" "$rvm_ruby_make_install" "Installing $rvm_ruby_string" result=$? if (( result > 0 )) then rvm_error "There has been an error while trying to run make install. exit $result fi rvm_log "Installation of $rvm_ruby_string is complete." export GEM_HOME="$rvm_ruby_gem_home" export GEM_PATH="$rvm_ruby_gem_path" ( rvm_create_flag=1 __rvm_use "$rvm_scripts_path/rubygems" ${rvm_rubygems_version:-latest} ) __rvm_bin_script __rvm_run "chmod.bin" "chmod +x $rvm_ruby_home/bin/*" __rvm_post_install rm $rvm_ruby_home/bin/ruby ln -s $rvm_ruby_home/bin/goruby $rvm_ruby_home/bin/ruby } \nHalting the installation." 1.18.61.24.2. ree #!/usr/bin/env bash ree_install() { if [[ -n "$(echo "$rvm_ruby_version" | awk '/^1\.8/')" ]] && (( rvm_head_flag == 0 )) then rvm_log "Installing Ruby Enterprise Edition from source to: $rvm_ruby_home" builtin cd "${rvm_src_path}" if [[ -d "${rvm_src_path}/$rvm_ruby_string" && -x "${rvm_src_path}/$rvm_ruby_string/installer" ]] then rvm_log "It appears that the archive has already been extracted. Skipping extract (use reinstall to do fresh installation)." else rvm_log "$rvm_ruby_string - #fetching ($rvm_ruby_package_file)" "$rvm_scripts_path/fetch" "$rvm_ruby_url" result=$? if (( result > 0 )) then rvm_error "There has been an error while trying to fetch the source. \nHalting the installation." return $result fi __rvm_rm_rf "${rvm_src_path}/$rvm_ruby_string" __rvm_run "extract" \ "gunzip < \"${rvm_archives_path}/$rvm_ruby_package_file.$rvm_archive_extension\" | $rvm_tar_command xf - -C ${rvm_src_path} ${rvm_tar_options:-}" \ "$rvm_ruby_string - #extracting $rvm_ruby_package_file to ${rvm_src_path}/$rvm_ruby_string" result=$? if (( result > 0 )) then rvm_error "There has been an error while trying to extract the source. Halting the installation." return $result fi mv "${rvm_src_path}/$rvm_ruby_package_file" \ "${rvm_src_path}/$rvm_ruby_string" fi builtin cd "${rvm_src_path}/$rvm_ruby_string" __rvm_setup_compile_environment # wait, what? v v v TODO: Investigate line smell. mkdir -p "${rvm_ruby_home}/lib/ruby/gems/1.8/gems" if [[ -n "$rvm_configure_flags" ]] then rvm_configure_flags="${rvm_configure_flags//--/-c --}" fi if [[ "Darwin" == "$(uname)" && ("1.8.6" == "$rvm_ruby_version" || "1.8.7" == "$rvm_ruby_version") && ! "$rvm_ree_options" =~ "--no-tcmalloc" ]] then rvm_ree_options="${rvm_ree_options} --no-tcmalloc" fi __rvm_db "${rvm_ruby_interpreter}_configure_flags" "db_configure_flags" __rvm_apply_patches "${rvm_src_path}/$rvm_ruby_string/source" result=$? if (( result == 0 )) && [[ "$(uname -m)" == "x86_64" ]] then ( full_patch_path="$(__rvm_lookup_full_patch_path lib64)" cd "${rvm_src_path}/$rvm_ruby_string" __rvm_run "patch.apply.lib64" \ "patch -F 3 -p1 -N -f <\"$full_patch_path\"" \ "Applying patch 'lib64' (located at $full_patch_path)" ) result=$? fi if (( result > 0 )) then rvm_error "There has been an error while trying to apply patches to ree. \nHalting the installation." return $result fi : rvm_configure_env:${rvm_configure_env:=""} __rvm_run "install" \ "${rvm_configure_env/CCFLAGS=/CFLAGS=} ./installer -a $rvm_rubies_path/$rvm_ruby_string \ $rvm_ree_options $db_configure_flags $rvm_configure_flags" "$rvm_ruby_string - #installing" result=$? if (( result > 0 )) then rvm_error "There has been an error while trying to run the ree installer. Halting the installation." return $result fi chmod +x "$rvm_ruby_home"/bin/* ( rvm_create_flag=1 __rvm_use "$rvm_scripts_path/rubygems" ${rvm_rubygems_version:-latest} ) __rvm_bin_script __rvm_post_install else __rvm_db "${rvm_ruby_interpreter}_${rvm_ruby_version}_repo_url" "rvm_ruby_url" if [[ -z "$rvm_ruby_url" ]] ; then rvm_error "rvm does not know the rvm repo url for '${rvm_ruby_interpreter}_${rvm_ruby_version}'" result=1 else rvm_ruby_repo_url="$rvm_ruby_url" __rvm_setup_compile_environment __rvm_install_source $* fi fi } 1.18.61.24.3. rubinius #!/usr/bin/env bash file_exists_at_url() { typeset _url _url="${1:-}" if [[ -n "${_url}" ]] then ( #subshell to be able to temporary disable curl function unset curl 2>/dev/null if curl -slk --head ${_url} 2>&1 | \head -n 1 | GREP_OPTIONS="" \grep '200 OK' >/dev/null 2>&1 then return 0 else return 1 fi ) else rvm_log "Warning: URL was not passed to __rvm_check_for_tarball" return 1 fi } rbx_configure_with_path() { typeset name path name="${1:-}" path="${2:-}" [[ -d "${path}" ]] || return 1 [[ -d "${path}/include" ]] || return 2 rvm_configure_args="${rvm_configure_args:-} --with-${name}-dir=${path}" rvm_configure_flags="${rvm_configure_flags:-} --with-opt-dir=${path}" return 0 } rbx_install() { typeset rvm_configure_args rvm_log "$rvm_ruby_string installing #dependencies " if ! __rvm_ensure_has_mri_ruby then rvm_log "No MRI ruby found, cannot build rbx." return 1 fi export ruby="$(__rvm_mri_ruby)" # TODO: use 'rvm gems load' here: unset CFLAGS LDFLAGS ARCHFLAGS # Important. unset GEM_HOME GEM_PATH MY_RUBY_HOME IRBRC __rvm_remove_rvm_from_path __rvm_conditionally_add_bin_path export PATH builtin hash -r case ${rvm_ruby_string} in rbx-head*|rbx-2.*) # #RBX 2.0 should now use libyaml which is for Psych. if ! libyaml_installed then libyaml # Installs libyaml fi rbx_configure_with_path libyaml "$rvm_path/usr" || { rvm_error "Could not find 'lib' dir for libyaml, please make sure libyaml is compiled properly." return 1 } ;; esac __rvm_compatibility_flag_configuration --default-version= if [[ -s "${rvm_archives_path}/${rvm_ruby_package_file}" ]] || [[ -n "${rvm_ruby_url:-}" ]] && file_exists_at_url "${rvm_ruby_url}" then rvm_head_flag=0 else rvm_head_flag=1 if [[ "${rvm_ruby_version}" == 'head' ]] then true ${rvm_ruby_repo_branch:="master"} else true ${rvm_ruby_repo_branch:="${rvm_ruby_version}"} fi fi if (( rvm_head_flag == 0 )) then # Install from tarball url. rvm_log "$rvm_ruby_string #downloading ($rvm_ruby_package_file), this may take a while depending on your connection..." "$rvm_scripts_path/fetch" "$rvm_ruby_url" result=$? if (( result > 0 )) then rvm_error "There has been an error while trying to fetch the source. Halting the installation." exit $result fi __rvm_run "extract" \ "gunzip < \"${rvm_archives_path}/$(basename ${rvm_ruby_package_file})\" | $rvm_tar_command xf - -C ${rvm_src_path} ${rvm_tar_options:-}" \ "$rvm_ruby_string - #extracting" result=$? if (( result > 0 )) then rvm_error "There has been an error while trying to extract the source. exit $result fi \nHalting the installation." # Remove the left over folder first. __rvm_rm_rf "${rvm_src_path}/$rvm_ruby_string" mv "${rvm_src_path}/rubinius-${rvm_ruby_version}" \ "${rvm_src_path}/$rvm_ruby_string" else # Install from repository __rvm_db "rubinius_repo_url" "rvm_ruby_repo_url" #rvm_ruby_home="$rvm_rubies_path/$rvm_ruby_interpreter-$rvm_ruby_version" __rvm_fetch_from_github "rbx" result=$? if (( result > 0 )) then rvm_error "There has been an error while fetching the rbx git repo. exit $result fi \nHalting the installation." fi builtin cd "${rvm_src_path}/$rvm_ruby_string" chmod +x ./configure __rvm_apply_patches result=$? if (( result > 0 )) then rvm_error "There has been an error while trying to apply patches to rubinius. return $result fi \nHalting the installation." __rvm_db "${rvm_ruby_interpreter}_configure_flags" "db_configure_flags" rvm_configure_flags="${rvm_configure_flags:-"--skip-system"}" rvm_ruby_configure="$rvm_wrappers_path/$ruby/ruby ${rvm_configure_env:-""} ./configure --prefix=$rvm_ruby_home $db_configure_flags $rvm_configure_flags ${rvm_install_args:-}" if (( ${rvm_llvm_flag:=1} == 0 )) then # Explicitely disabled rvm_ruby_configure="$rvm_ruby_configure --disable-llvm" fi __rvm_run "configure" "$rvm_ruby_configure" "$rvm_ruby_string - #configuring" result=$? if (( result > 0 )) then rvm_error "There has been an error while running '$rvm_ruby_configure'. exit $result fi \nHalting the installation." if [[ -n "${rvm_configure_args:-}" ]] then rvm_ruby_make="CONFIGURE_ARGS=${rvm_configure_args## } " fi rvm_ruby_make="${rvm_ruby_make:-}$rvm_wrappers_path/$ruby/rake install --trace" __rvm_run "rake" "$rvm_ruby_make" "$rvm_ruby_string - #compiling" result=$? if (( result > 0 )) || ! [[ -d "$rvm_ruby_home" ]] || ! [[ -f "$rvm_ruby_home/bin/rbx" ]] then rvm_error "There has been an error while running '$rvm_ruby_make'.\nHalting the installation." exit $result fi unset ruby # Symlink rubinius wrapper if not available [[ -f "$rvm_ruby_home/bin/ruby" ]] || ln -fs "$rvm_ruby_home/bin/rbx" "$rvm_ruby_home/bin/ruby" case ${rvm_ruby_string} in rbx-head*|rbx-2.*) true ;; *) # older rbx had issues # Install IRB Wrapper on Rubinius. file_name="$rvm_ruby_home/bin/irb" rm -f "$file_name" printf "%b" '#!/usr/bin/env bash\n' > "$file_name" printf "%b" "exec '$rvm_ruby_home/bin/rbx' 'irb' \"\$@\"\n" >> "$file_name" [[ -x "$file_name" ]] || chmod +x "$file_name" # Install Gem Wrapper on Rubinius. file_name="$rvm_ruby_home/bin/gem" cp -f "$rvm_ruby_home/lib/bin/gem.rb" "$file_name" __rvm_inject_ruby_shebang "$file_name" [[ -x "$file_name" ]] || chmod +x "$file_name" unset file_name ;; esac ( rvm_create_flag=1 __rvm_use ) case ${rvm_ruby_string} in rbx-head*|rbx-2.*) binaries=() ;; *) binaries=(erb ri rdoc) ;; esac __rvm_post_install __rvm_bin_script } 1.18.61.24.4. ruby #!/usr/bin/env bash transform_configure_flags() { typeset flag path typeset -a new_flags for flag in ${rvm_configure_flags} do case "${flag}" in --with-opt-dir=*) new_flags+=( "${flag}" ) ;; --with-*-dir=*) path="${flag#*=}" flag="${flag%-dir=*}" new_flags+=( "${flag}" ) if ! [[ " ${new_flags[*]} " =~ " --with-opt-dir=${path} " ]] then new_flags+=( "--with-opt-dir=${path}" ) fi ;; *) new_flags+=( "${flag}" ) ;; esac done rvm_configure_flags="${new_flags[*]}" } # 1.9.3-p125+ __clang_ready() { typeset _patch_level case ${rvm_ruby_string} in ruby-1.9.3-head*|ruby-2*) return 0 ;; ruby-1.9.3*) _patch_level="${rvm_ruby_patch_level:-p0}" _patch_level="${_patch_level#p}" (( _patch_level >= 125 )) && return 0 || true ;; esac return 1 } ruby_install() { typeset result temp_flags __rvm_check_for_bison # && Run like hell... if __rvm_check_for_bison then true else result=$? rvm_log "Bison required but not found. Halting." exit $result fi case ${rvm_ruby_string:-""} in ruby-1.8*|ree*|ruby-1.9*) true # carry on then, nothing to see here :P ;; ruby-head|1.9.*-head) if __rvm_ensure_has_mri_ruby "1.8.|ree" then true else return $? fi ;; esac case ${rvm_ruby_string} in ruby-1.9*) # Ruby 1.9 should now use libyaml which is for Psych. if [[ " ${rvm_configure_flags[*]}" =~ " --with-opt-dir=" ]] then rvm_warn "Please note that you are using your own '--with-opt-dir=', make sure 'libyaml' is installed and available for ruby compilation." else if ! libyaml_installed then libyaml # Installs libyaml fi rvm_configure_flags="${rvm_configure_flags:-} --with-libyaml-dir=${rvm_path}/usr" fi # Ruby 1.9 does not allow --with-<lib>-dir, # so we transform it to --with-<lib> --with-opt-dir=... # see https://github.com/wayneeseguin/rvm/issues/674 temp_flags=" ${rvm_configure_flags[*]}" temp_flags="${temp_flags// --with-opt-dir=/}" if [[ " ${rvm_configure_flags[*]}" =~ " --with-opt-dir=" && "${temp_flags}" =~ "-dir=" ]] then rvm_warn "You are using conflicting '--*-dir=' configure flags." else transform_configure_flags fi ;; esac # Temporary solution for this bug http://bugs.ruby-lang.org/issues/5384 case "$(uname -s)" in SunOS) case ${rvm_ruby_string} in ruby-1.9*) rvm_configure_flags="${rvm_configure_flags:-} ac_cv_func_dl_iterate_phdr=no" ;; esac ;; esac __rvm_setup_compile_environment # Force using clang when only LLVM available and user did not selected compiler, # hides the need for `rvm_force_autoconf=1` # which should be default, but is not by default available on Xcode 4.3. if [[ "$MACHTYPE" == *darwin* ]] && __clang_ready && __rvm_compiler_is_llvm && ! __rvm_selected_compiler > /dev/null then rvm_configure_flags="${rvm_configure_flags:-""} --with-gcc=clang" fi if __rvm_compiler_is_llvm then if __clang_ready || __rvm_selected_compiler > /dev/null then rvm_warn "Building '${rvm_ruby_string}' using clang - but it's not (fully) supported, expect errors." else rvm_error "The provided compiler '$(__rvm_found_compiler)' is LLVM based, it is not yet fully supported by ruby and gems, please read \`rvm requirements\`." exit 1 fi fi ( __rvm_install_source $* ) result=$? if __rvm_compiler_is_llvm then rvm_warn "Ruby '${rvm_ruby_string}' was build using clang - but it's not (fully) supported, expect errors." rvm_warn "Ruby '${rvm_ruby_string}' was built using clang - but it's not (fully) supported, expect errors." fi typeset patches_count patches_count=$( rvm_ruby_string="${rvm_ruby_string}" "$rvm_scripts_path/patchsets" show default | wc -l ) # 1.9.3 provides a patch to compile better with LLVM if [[ ! "${rvm_ruby_string}" =~ "ruby-1.9.3" ]] && (( patches_count > 0 )) then rvm_warn "Please be aware that you just installed a ruby that requires ${patches_count} patches just to be compiled on up to date linux system. This may have known and unaccounted for security vulnerabilities. Please consider upgrading to Ruby $(__rvm_db "ruby_version")-$(__rvm_db "ruby_patchlevel") which will have all of the latest security patches." fi return ${result:-0} } 1.18.61.24.5. macruby #!/usr/bin/env bash macruby_install() { if [[ "Darwin" != "$(uname)" ]] then rvm_error "MacRuby can only be installed on a Darwin OS." exit 1 fi if (( rvm_head_flag == 1 )) then if (( ${rvm_llvm_flag:=0} == 1 )) then "$rvm_scripts_path/package" llvm install fi macruby_path="/usr/local/bin" # TODO: configure & make variables should be set here. rvm_ruby_configure=" true " rvm_ruby_make="rake" rvm_ruby_make_install="$rvm_bin_path/rvmsudo rake install" __rvm_db "${rvm_ruby_interpreter}_repo_url" "rvm_ruby_url" rvm_ruby_repo_url=$rvm_ruby_url __rvm_setup_compile_environment __rvm_install_source $* result=$? if (( result > 0 )) then rvm_error "There has been an error while trying to install from source. \nHalting the installation." return $result fi elif [[ "nightly" == "$rvm_ruby_version" ]] ; then __rvm_db "macruby_nightly_version" "macruby_nightly_version" macruby_path="/Library/Frameworks/MacRuby.framework/Versions/${macruby_nightly_version}/usr/bin" unset macruby_nightly_version # TODO: Separated nightly from head. rvm_log "Retrieving the latest nightly macruby build..." "$rvm_scripts_path/fetch" "$rvm_ruby_url" result=$? if (( result > 0 )) then rvm_error "There has been an error while trying to fetch the source. return $result fi \nHalting the installation." mv "${rvm_archives_path}/macruby_nightly-latest.pkg" \ "${rvm_archives_path}/macruby_nightly.pkg" __rvm_run "macruby/extract" \ "sudo /usr/sbin/installer -pkg '${rvm_archives_path}/macruby_nightly.pkg' -target '/'" mkdir -p "$rvm_ruby_home/bin" else macruby_path="/Library/Frameworks/MacRuby.framework/Versions/${rvm_ruby_version}/usr/bin" # TODO: Separated nightly from head. rvm_log "Retrieving MacRuby ${rvm_ruby_version} ..." "$rvm_scripts_path/fetch" "$rvm_ruby_url" result=$? if (( result > 0 )) then rvm_error "There has been an error while trying to fetch the source. Halting the installation." return $result fi mkdir -p ${rvm_src_path}/$rvm_ruby_string unzip -o -j "${rvm_archives_path}/$rvm_ruby_package_file" \ "MacRuby ${rvm_ruby_version}/MacRuby ${rvm_ruby_version}.pkg" \ -d "${rvm_src_path}/$rvm_ruby_string" mv "${rvm_src_path}/$rvm_ruby_string/MacRuby ${rvm_ruby_version}.pkg" \ "${rvm_src_path}/$rvm_ruby_string/$rvm_ruby_string.pkg" __rvm_run "macruby/extract" \ "sudo /usr/sbin/installer -pkg '${rvm_src_path}/$rvm_ruby_string/$rvm_ruby_string.pkg' -target '/'" mkdir -p "$rvm_ruby_home/bin" fi ( rvm_create_flag=1 __rvm_use ) binaries=(erb gem irb rake rdoc ri ruby testrb) for binary_name in ${binaries[@]}; do # TODO: This should be generated via an external script. ruby_wrapper=$(cat <<RubyWrapper #!/usr/bin/env bash export export export export GEM_HOME="\${GEM_HOME:-$rvm_ruby_gem_home}" GEM_PATH="\${GEM_PATH:-$rvm_ruby_gem_path}" MY_RUBY_HOME="$rvm_ruby_home" PATH="$rvm_ruby_gem_home/bin:$rvm_ruby_global_gems_path/bin:$rvm_ruby_home/bin:\$PATH" exec "$macruby_path/mac$binary_name" "\$@" RubyWrapper ) file_name="$rvm_ruby_home/bin/$binary_name" if [[ -f "$file_name" ]] then rm -f "$file_name" fi echo "$ruby_wrapper" > "$file_name" if [[ ! -x "$file_name" ]] then chmod +x $file_name fi if [[ "$binary_name" == "ruby" ]] then rm -f "${rvm_bin_path:-"$rvm_path/bin"}/$rvm_ruby_string" echo "$ruby_wrapper" \ > "${rvm_bin_path:-"$rvm_path/bin"}/$rvm_ruby_string" fi done unset binaries __rvm_irbrc } 1.18.61.24.6. maglev #!/usr/bin/env bash maglev_install() { __rvm_ensure_has_mri_ruby compatible_ruby="$(__rvm_mri_ruby)" rvm_log "Running MagLev prereqs checking script." "$rvm_scripts_path/maglev" result=$? if (( result > 0 )) then rvm_error "Prerequisite checks have failed. \nHalting the installation." exit $result fi builtin cd "${rvm_src_path}" system="$(uname -s)" arch="$(uname -m)" [ "${system}-${arch}" == "Darwin-x86_64" ] && arch="i386" if [[ ! -d "${rvm_src_path}/$rvm_ruby_string" ]] || (( ${rvm_head_flag:=0} == 1 )) then __rvm_fetch_ruby result=$? if (( result > 0 )) then rvm_error "There has been an error while trying to fetch the source. exit $result fi \nHalting the installation." fi if (( ${rvm_head_flag:=0} == 1 )) then builtin cd "${rvm_src_path}/$rvm_ruby_string" rvm_gemstone_package_file="GemStone-$(GREP_OPTIONS="" \grep ^GEMSTONE version.txt | cut -f2 -d-).${system}-${arch}" rvm_gemstone_url="$maglev_url/${rvm_gemstone_package_file}.${rvm_archive_extension}" fi rvm_log "Downloading the GemStone package, this may take a while depending on your connection..." "$rvm_scripts_path/fetch" "$rvm_gemstone_url" result=$? if (( result > 0 )) then rvm_error "There has been an error while trying to fetch the GemStone package.\nHalting the installation." exit $result fi builtin cd "${rvm_src_path}" if [[ -s "$rvm_ruby_package_file" ]] then mv "$rvm_ruby_package_file" "${rvm_src_path}/$rvm_ruby_string" fi builtin cd "${rvm_src_path}/$rvm_ruby_string" if [[ -d ${rvm_src_path}/${rvm_gemstone_package_file} ]] then __rvm_run "gemstone.fix_rights" \ "chmod -R u+w ${rvm_src_path}/${rvm_gemstone_package_file}" else mkdir -p "${rvm_src_path}/${rvm_gemstone_package_file}" fi __rvm_run "gemstone.extract" \ "$rvm_tar_command xzf \"${rvm_archives_path}/${rvm_gemstone_package_file}.${rvm_archive_extension}\" -C ${rvm_src_path}/ ${rvm_tar_options:-}" result=$? if (( result > 0 )) then rvm_error "There has been an error while trying to extract the GemStone package. \nHalting the installation." exit $result fi ln -fs "${rvm_src_path}/$rvm_gemstone_package_file" "gemstone" __rvm_rm_rf $rvm_ruby_home __rvm_run "install" \ "/bin/cp -Rf ${rvm_src_path}/$rvm_ruby_string $rvm_ruby_home" \ "Installing maglev to $rvm_ruby_home" ( builtin cd "$rvm_ruby_home/bin/" for binary in maglev-irb maglev-ruby maglev-gem do ln -fs "$binary" "${binary#maglev-}" done unset binary ) binaries=(maglev-ruby maglev-irb maglev-gem) for binary in "${binaries[@]}" do __rvm_inject_gem_env "$rvm_ruby_home/bin/$binary" done builtin cd "$rvm_ruby_home" if (( ${rvm_head_flag:=0} == 1 )) then git submodule update --init "$rvm_ruby_home/bin/maglev" force-reload fi ln -fs maglev.demo.key-${system}-${arch} etc/maglev.demo.key rvm_log "Bootstrapping a new image" "$rvm_wrappers_path/$compatible_ruby/rake" "build:maglev" if [[ ! -e ${rvm_ruby_home}/etc/conf.d/maglev.conf ]] then rvm_log "Creating default 'maglev' repository." "$rvm_wrappers_path/$compatible_ruby/rake" "stone:create[maglev]" >/dev/null 2>&1 fi rvm_log "Generating maglev HTML documentation" "$rvm_wrappers_path/$compatible_ruby/rake" rdoc >/dev/null 2>&1 rvm_log "Generating smalltalk FFI." "$rvm_wrappers_path/$compatible_ruby/rake" stwrappers >/dev/null 2>&1 # maglev ships with some built in gems, copy them in to place. if [[ -d "$rvm_ruby_home/lib/maglev/gems/1.8" ]] then rvm_log "Copying across included gems" cp -R "$rvm_ruby_home/lib/maglev/gems/1.8/" "$rvm_ruby_gem_home/" fi unset compatible_ruby # MagLev comes with RubyGems preinstalled -- don't try to install it # "$rvm_scripts_path/rubygems" latest __rvm_irbrc __rvm_bin_script rvm_create_flag=1 __rvm_use } 1.18.61.24.7. ironruby #!/usr/bin/env bash ironruby_install() { if ! builtin command -v mono > /dev/null then printf "%b" "mono must be installed and in your path in order to install IronRuby." ; return 1 fi if (( ${rvm_head_flag:=0} == 1 )) then mono_version="$(mono -V | head -n 1 | cut -d ' ' -f5)" if "$rvm_scripts_path/match" "$mono_version" "([0-9]+)\.([0-9]+)\.?([0-9]+)?" then mono_major_ver="$(echo "$mono_version" | cut -d '.' -f1)" mono_minor_ver="$(echo "$mono_version" | cut -d '.' -f2)" if [[ $mono_major_ver -lt 2 ]] || ( [[ $mono_major_ver -eq 2 && $mono_minor_ver -lt 6 ]] ) then printf "%b" "Mono 2.6 (or greater) must be installed and in your path in order to build IronRuby from the repository." printf "%b" "Version detected: ${mono_version}" return 1 fi else printf "%b" "Cannot recognize mono version." return 1 fi __rvm_ensure_has_mri_ruby __rvm_fetch_ruby result=$? if (( result > 0 )) then return $result fi builtin cd "${rvm_src_path}/$rvm_ruby_string" compatible_ruby="$(__rvm_mri_ruby)" "$rvm_wrappers_path/$compatible_ruby/gem" install pathname2 --no-rdoc --no-ri # MONO_LIB=/Library/Frameworks/Mono.framework/Versions/current/lib/ rvm_ruby_make="$rvm_wrappers_path/$compatible_ruby/rake MERLIN_ROOT=\"${rvm_src_path}/$rvm_ruby_string/Merlin/Main\" compile mono=1 configuration=release --trace" __rvm_run "rake" "$rvm_ruby_make" "Building IronRuby..." unset compatible_ruby result=$? if (( result > 0 )) then exit $result fi __rvm_rm_rf "$rvm_ruby_home"/* mkdir -p "$rvm_ruby_home/bin" "$rvm_ruby_home/lib" \ "$rvm_ruby_home/lib/ruby" "$rvm_ruby_home/lib/IronRuby" cp -r "${rvm_src_path}/$rvm_ruby_string/Merlin/Main/Bin/mono_release"/* "$rvm_ruby_home/bin/" cp -r "${rvm_src_path}/$rvm_ruby_string/Merlin/Main/Languages/Ruby/Scripts/bin"/* "$rvm_ruby_home/bin/" cp -r "${rvm_src_path}/$rvm_ruby_string/Merlin/External.LCA_RESTRICTED/Languages/Ruby/redist-libs/ruby"/* "$rvm_ruby_home/lib/ruby" cp -r "${rvm_src_path}/$rvm_ruby_string/Merlin/Main/Languages/Ruby/Libs"/* "$rvm_ruby_home/lib/IronRuby" else rvm_log "Retrieving IronRuby" "$rvm_scripts_path/fetch" "$rvm_ruby_url" \ "$rvm_ruby_package_file" result=$? if (( result > 0 )) then rvm_error "There has been an error while trying to fetch the source. \nHalting the installation." exit $result fi mkdir -p "${rvm_src_path}/$rvm_ruby_string" "$rvm_ruby_home" unzip -o -d "${rvm_src_path}/$rvm_ruby_string" \ "${rvm_archives_path}/${rvm_ruby_package_file}" >> \ "${rvm_log_path}/$rvm_ruby_string/extract.log" 2>&1 result=$? if (( result > 1 )) then rvm_error "There has been an error while trying to extract $rvm_ruby_package_file.\n${rvm_log_path}/$rvm_ruby_string/extract.log might have more details.\nHalting the installation." exit $result fi for dir in bin lib silverlight do cp -Rf "${rvm_src_path}/$rvm_ruby_string/$dir" "$rvm_ruby_home/$dir" done fi binaries=(gem irb rdoc rake ri ruby) for binary_name in "${binaries[@]}" do if [[ -s "$rvm_ruby_home/bin/$binary_name" ]] then \tr -d '\r' < "$rvm_ruby_home/bin/$binary_name" > "$rvm_ruby_home/bin/$binary_name.new" #sed -e '1,1s=.*=#!'"/usr/bin/env ir=" "$rvm_ruby_home/bin/$binary_name" > "$rvm_ruby_home/bin/$binary_name.new" mv -f "$rvm_ruby_home/bin/$binary_name.new" "$rvm_ruby_home/bin/$binary_name" chmod +x "$rvm_ruby_home/bin/$binary_name" fi done ; unset binaries sed -e '1,1s=.*=#!'"/usr/bin/env bash=" "$rvm_ruby_home/bin/ir" \ | \tr -d '\r' > "$rvm_ruby_home/bin/ir.new" mv -f "$rvm_ruby_home/bin/ir.new" "$rvm_ruby_home/bin/ir" chmod +x "$rvm_ruby_home/bin/ir" ln -fs "$rvm_ruby_home/bin/ir" "$rvm_ruby_home/bin/ruby" ( rvm_create_flag=1 __rvm_use ) builtin hash -r __rvm_run "gems.install" \ "PATH=\"$rvm_ruby_gem_home/bin:$rvm_ruby_global_gems_path/bin:$rvm_ruby_home/bin:$PATH\" GEM_HOME=\"$rvm_ruby_gem_home\" GEM_PATH=\"$rvm_ruby_gem_home:$rvm_ruby_global_gems_path\" $rvm_ruby_home/bin/gem install --no-rdoc --no-ri rake $rvm_gem_options" \ "Installing $rvm_gem_name to $dir" } 1.18.61.24.8. jruby #!/usr/bin/env bash jruby_install() { __rvm_compatibility_flag_configuration -Djruby.default.ruby.version= if ! builtin command -v java > /dev/null then printf "%b" "java must be installed and in PATH for JRuby." return 1 fi if [[ -n "$JRUBY_HOME" ]] then printf "%b" "You have environment variable JRUBY_HOME set, please unset it before installing/using JRuby." return 2 fi if [[ "Darwin" == "$(uname)" ]] then java_version=$(java -version 2>&1 | awk -F'"' '/ version /{print $2}') case "$java_version" in (1.5.*) printf "%b" "\n\nWARNING: A very outdated JAVA version is being used ($java_version), it is strongly recommended that you upgrade to the latest version.\n\n" ;; (1.3.*|1.4.*) printf "%b" "\n\nERROR: Unsupported JAVA version $java_version. In order to install and use JRuby you must upgrade to the latest JAVA version.\n\n" exit 1 ;; esac fi builtin cd "${rvm_src_path}" __rvm_fetch_ruby result=$? if (( result > 0 )) then rvm_error "There has been an error while trying to fetch the source. exit $result fi \nHalting the installation." builtin cd "${rvm_src_path}/$rvm_ruby_string" if [[ -n ${rvm_configure_flags:-} ]] || (( ${rvm_head_flag:=0} )) then __rvm_apply_patches __rvm_run "ant.jar" "ant jar" "$rvm_ruby_string - #ant jar" if [[ -n ${rvm_configure_flags:-} ]] then __rvm_run "ant.jar.flags" "ant jar ${rvm_configure_flags}" "$rvm_ruby_string - #ant jar ${rvm_configure_flags}" fi fi if (( ${rvm_head_flag:=0} )) then __rvm_run "ant.cext" "ant cext ${rvm_configure_flags}" "$rvm_ruby_string - #ant cext" || \ rvm_warn "cext is know to fail please report here: https://jira.codehaus.org/browse/JRUBY" fi mkdir -p "$rvm_ruby_home/bin/" case "$rvm_ruby_version" in 1.2*|1.3*) __rvm_run "nailgun" \ "builtin cd \"${rvm_src_path}/$rvm_ruby_string/tool/nailgun\" && make $rvm_make_flags" \ "Building Nailgun" ;; *) __rvm_run "nailgun" \ "builtin cd \"${rvm_src_path}/$rvm_ruby_string/tool/nailgun\" && ${rvm_configure_env:-""} ./configure -prefix=$rvm_ruby_home && make $rvm_make_flags" \ "Building Nailgun" ;; esac __rvm_rm_rf "$rvm_ruby_home" __rvm_run "install" \ "/bin/cp -Rf ${rvm_src_path}/$rvm_ruby_string $rvm_ruby_home" "$rvm_ruby_string - #installing to $rvm_ruby_home" ( builtin cd "$rvm_ruby_home/bin/" for binary in jirb jruby jgem ; do ln -fs "$binary" "${binary#j}" done ) # -server is "a lot slower for short-lived scripts like rake tasks, and takes longer to load" #sed -e 's#^JAVA_VM=-client#JAVA_VM=-server#' $rvm_ruby_home/bin/jruby > $rvm_ruby_home/bin/jruby.new && # mv $rvm_ruby_home/bin/jruby.new $rvm_ruby_home/bin/jruby chmod +x "$rvm_ruby_home/bin/jruby" binaries=(jrubyc jirb_swing jirb jgem rdoc ri spec autospec testrb ast generate_yaml_index.rb) for binary in "${binaries[@]}" do __rvm_inject_gem_env "$rvm_ruby_home/bin/$binary" done __rvm_inject_ruby_shebang "$rvm_ruby_home/bin/rake" __rvm_irbrc rvm_create_flag=1 __rvm_use __rvm_bin_script __rvm_post_install # jruby ships with some built in gems, copy them in to place. if [[ -d "$rvm_ruby_home/lib/ruby/gems/1.8" ]] then rvm_log "Copying across included gems" cp -R "$rvm_ruby_home/lib/ruby/gems/1.8/" "$rvm_ruby_gem_home/" fi } 1.18.61.24.9. base #!/usr/bin/env bash # Emits a number of patches to STDOUT, each on a new name # Expands patchsets etc. __rvm_current_patch_names() { # TODO: Lookup default patches on rvm_ruby_string heirarchy. typeset separator patches level name separator="%" patches="${rvm_patch_names:-""} default" for name in $(echo ${patches//,/ }) do if [[ "${name//${separator}*/}" == "${name}" ]] then level=1 else level="${name/*${separator}/}" name="${name//${separator}*/}" fi typeset expanded_name expanded_name="$( __rvm_expand_patch_name "$name" )" if [[ -n "${name}" && -n "${expanded_name}" ]] then echo "${expanded_name}${separator}${level}" fi done return 0 } __rvm_apply_patches() { typeset patches patch_name patch_level_separator patch_fuzziness patch_level source_directory full_patch_path result=0 patch_level_separator="%" patch_fuzziness="25" # max fuziness that makes sense is 3 (or there are patches with bigger context ?) patch_level=1 source_directory="${1:-""}" if [[ -z "$source_directory" ]] then source_directory="${rvm_src_path}/$rvm_ruby_string" fi ( builtin cd "$source_directory" patches=($(__rvm_current_patch_names)) for patch_name in ${patches[*]} do # If set, extract the patch level from the patch name. patch_level=1 if echo "$patch_name" | GREP_OPTIONS="" \grep "$patch_level_separator" >/dev/null 2>&1; then patch_level=${patch_name//*${patch_level_separator}/} patch_name="${patch_name//${patch_level_separator}*/}" fi full_patch_path="$(__rvm_lookup_full_patch_path "$patch_name")" # Expand paths, and for those we found we then apply the patches. if [[ -n "${full_patch_path:-""}" ]] then if [[ -f "$full_patch_path" ]] then __rvm_run "patch.apply.${patch_name/*\/}" \ "patch -F $patch_fuzziness -p$patch_level -N -f <\"$full_patch_path\"" \ "Applying patch '$patch_name' (located at $full_patch_path)" if (( $? > 0 )) then result=1 # Detect failed patches fi fi else rvm_warn "Patch '$patch_name' not found." result=1 fi done ) return ${result:-0} } __rvm_install_source() { true ${rvm_ruby_selected_flag:=0} ${rvm_static_flag:=0} typeset directory configure_parameters db_configure_flags autoconf_flags if (( rvm_ruby_selected_flag == 0 )) then __rvm_select fi rvm_log "Installing Ruby from source to: $rvm_ruby_home, this may take a while depending on your cpu(s)...\n" builtin cd "${rvm_src_path}" __rvm_fetch_ruby result=$? if (( result > 0 )) then rvm_error "There has been an error fetching the ruby interpreter. Halting the installation." return $result fi builtin cd "${rvm_src_path}/$rvm_ruby_string" result=$? if (( result > 0 )) then rvm_error "Source directory is missing. \nDid the download or extraction fail? return $result fi \nHalting the installation." if [[ -d "${rvm_path}/usr" ]] then __rvm_add_to_path prepend "${rvm_path}/usr/bin" builtin hash -r fi if (( rvm_static_flag == 1 )) then if [[ -s "ext/Setup" ]] then echo 'option nodynamic' >> ext/Setup rvm_log "Setting option nodynamic (static)." else rvm_log " You asked for static Ruby compilation however the file ext/Setup appears to be missing from the source directory ${rvm_src_path}/$rvm_ruby_string please investigate this, continuing installation regardless. " fi fi __rvm_apply_patches result="$?" if (( result > 0 )) then rvm_error "There has been an error applying the specified patches. Halting the installation." return $result fi if [[ -z "${rvm_ruby_configure:-""}" \ && (! -s "${rvm_src_path}/$rvm_ruby_string/configure" \ || "${rvm_src_path}/$rvm_ruby_string/configure.in" -nt "${rvm_src_path}/$rvm_ruby_string/configure") ]] || (( ${rvm_force_autoconf_flag:-0} == 1 )) then if builtin command -v autoreconf > /dev/null then if (( ${rvm_force_autoconf_flag:-0} == 1 )) then autoconf_flags=" -f" fi __rvm_run "autoreconf" "autoreconf${autoconf_flags:-}" "$rvm_ruby_string - #autoreconf${autoconf_flags:-}" else rvm_error "rvm requires autoreconf to install the selected ruby interpreter however autoreconf was not found in the PATH." exit 1 fi fi if [[ -n "${rvm_ruby_configure:-""}" ]] then __rvm_run "configure" "$rvm_ruby_configure" result=$? if (( result > 0 )) then rvm_error "There has been an error while configuring. Halting the installation." return $result fi elif [[ -s ./configure ]] then # REE stores configure flags differently for head vs. the distributed release. if [[ "ree" != "${rvm_ruby_interpreter:-""}" ]] then __rvm_db "${rvm_ruby_interpreter}_configure_flags" "db_configure_flags" fi # On 1.9.*-head, we manually set the --with-baseruby option # to point to an expanded path. case "${rvm_ruby_string:-""}" in ruby-head|ruby-1.9.3-head) typeset compatible_baseruby compatible_baseruby="$rvm_wrappers_path/$(__rvm_mri_ruby "1.8|ree")/ruby" if [[ -x "$compatible_baseruby" ]] then configure_parameters="--with-baseruby=$compatible_baseruby" fi ;; esac typeset configure_command configure_command="${rvm_configure_env:-""} ./configure --prefix=$rvm_ruby_home ${db_configure_flags:-""} ${rvm_configure_flags:-""} ${configure_parameters:-""}" __rvm_run "configure" "$configure_command" "$rvm_ruby_string - #configuring " result=$? if (( result > 0 )) then rvm_error "There has been an error while running configure. Halting the installation." return $result fi else rvm_error "Skipping configure step, 'configure' does not exist, did autoreconf not run successfully?" fi rvm_ruby_make=${rvm_ruby_make:-"make"} __rvm_run "make" "$rvm_ruby_make ${rvm_make_flags:-""}" "$rvm_ruby_string - #compiling " result=$? if (( result > 0 )) then rvm_error "There has been an error while running make. Halting the installation." return $result fi __rvm_rm_rf "$PWD/.ext/rdoc" rvm_ruby_make_install=${rvm_ruby_make_install:-"make install"} __rvm_run "install" "$rvm_ruby_make_install" "$rvm_ruby_string - #installing " result=$? if (( result > 0 )) then rvm_error "There has been an error while running make install. Halting the installation." return $result fi case "${rvm_ruby_string:-""}" in ruby-1.8.4|ruby-1.8.5-*) typeset libdir libdir="$rvm_ruby_home/lib" if [[ -d "${libdir}64" ]] then rm -rf "${libdir}" ln -s "${libdir}64" "${libdir}" fi ;; esac : rvm_configure_flags:${rvm_configure_flags:=}: case "${rvm_configure_flags}" in (*--program-suffix=*) typeset program_suffix program_suffix="${rvm_configure_flags#*--program-suffix=}" program_suffix="${program_suffix%%[\' ]*}" __rvm_run "link.ruby" "ln -s \"$rvm_ruby_home/bin/ruby${program_suffix}\" \ \"$rvm_ruby_home/bin/ruby\"" "$rvm_ruby_string - #linking ruby${program_suffix} -> ruby " ;; esac export GEM_HOME="$rvm_ruby_gem_home" export GEM_PATH="$rvm_ruby_gem_path" ( rvm_create_flag=1 __rvm_use "$rvm_scripts_path/rubygems" ${rvm_rubygems_version:-latest} ) result=$? __rvm_bin_script __rvm_run "chmod.bin" "chmod +x $rvm_ruby_home/bin/*" __rvm_post_install result=$? rvm_log "Install of $rvm_ruby_string - #complete " return ${result:-0} } __rvm_install_ruby() { true ${rvm_head_flag:=0} ${rvm_ruby_selected_flag:=0} typeset binary __rvm_ruby_name if (( rvm_ruby_selected_flag == 0 )) then __rvm_ruby_name="$rvm_ruby_name" __rvm_select || return $? if [[ -n "$__rvm_ruby_name" ]] then __rvm_select || return $? if [[ "$__rvm_ruby_name" != "$detected_rvm_ruby_name" ]] then rvm_error " The used ruby name (-n) is not valid, it was matched as: $( env | GREP_OPTIONS="" \grep "^rvm.*=$__rvm_ruby_name$" || printf "# Was not used at all\n") for more details on selecting names please visit: https://rvm.io/rubies/named/ " #" fix escaping return 1 fi fi fi if [[ -n "${RUBYOPT:-""}" ]] then ruby_options="$RUBYOPT" fi unset RUBYOPT if __rvm_check_for_compiler then true # sok else return $? fi case "${rvm_ruby_interpreter}" in macruby|ree|jruby|maglev|goruby) source "$rvm_scripts_path/functions/manage/${rvm_ruby_interpreter}" ${rvm_ruby_interpreter}_install ;; rbx|rubinius) source "$rvm_scripts_path/functions/manage/rubinius" rbx_install ;; ironruby|ir) source "$rvm_scripts_path/functions/manage/ironruby" ironruby_install ;; ruby|kiji|tcs) source "$rvm_scripts_path/functions/manage/ruby" ruby_install ;; default) rvm_error "a ruby interpreter to install must be specified and not simply 'default'." ;; *) rvm_error "Either the ruby interpreter is unknown or there was an error!." ;; esac # Record the Ruby's configuration to a file, key=value format. "$rvm_ruby_home/bin/ruby" -rrbconfig \ -e 'File.open(RbConfig::CONFIG["prefix"] + "/config","w") { |file| RbConfig::CONFIG.each_pair{|key,value| file.write("#{key.gsub(/\.|-/,"_")}=\"#{value.gsub("$","\\$")}\"\n")} }' >/dev/null 2>&1 rvm_hook="after_install" source "$rvm_scripts_path/hook" if [[ -n "$ruby_options" ]] then RUBYOPT="$ruby_options" export RUBYOPT fi } __rvm_fetch_from_git_revision_or_sha() { typeset result if [[ -n "$rvm_ruby_revision" ]] then ( cd "${rvm_repos_path}/${rvm_ruby_interpreter}" [[ "$rvm_ruby_revision" != "head" ]] || rvm_ruby_revision="master" git checkout -f "${rvm_ruby_revision}" ) result=$? elif [[ -n "${rvm_ruby_sha:-}" ]] then ( cd "${rvm_repos_path}/${rvm_ruby_interpreter}" git checkout -f "${rvm_ruby_sha}" ) result=$? fi if (( result > 0 )) then rvm_error "There has been an error while trying to checkout the source branch.\nHalting the installation." return $result fi } __rvm_fetch_from_github() { __rvm_rm_rf "${rvm_src_path}/$rvm_ruby_string" if [[ -d "${rvm_repos_path}/${rvm_ruby_interpreter}/.git" ]] then typeset existing_uri existing_uri="$( cd "${rvm_repos_path}/${rvm_ruby_interpreter}" >/dev/null git remote -v 2>/dev/null | awk '/^origin.*fetch/ {print $2}' )" if [[ "$rvm_ruby_repo_url" != "$existing_uri" ]] then \rm -rf "${rvm_repos_path}/${rvm_ruby_interpreter}" fi fi if [[ ! -d "${rvm_repos_path}/${rvm_ruby_interpreter}/.git" ]] then if [[ -d "${rvm_repos_path}/${rvm_ruby_interpreter}" ]] then \rm -rf "${rvm_repos_path}/${rvm_ruby_interpreter}" fi builtin cd "$rvm_home" __rvm_run "$1.repo" \ "git clone --depth 1 $rvm_ruby_repo_url ${rvm_repos_path}/${rvm_ruby_interpreter}" \ "Cloning $rvm_ruby_repo_url" result=$? if (( result > 0 )) then rvm_ruby_repo_http_url="${rvm_ruby_repo_url//git:/http:}" rvm_log "Could not fetch $rvm_ruby_repo_url - trying $rvm_ruby_repo_http_url" __rvm_run "$1.repo" "git clone --depth 1 $rvm_ruby_repo_http_url ${rvm_repos_path}/${rvm_ruby_interpreter}" "Cloning $rvm_ruby_repo_http_url" fi else typeset branch branch="${rvm_ruby_repo_branch:-"master"}" builtin cd "${rvm_repos_path}/${rvm_ruby_interpreter}" __rvm_run "$1.clean" "git checkout -f master ; git reset --hard HEAD ; rm -fr .git/rebase-apply" "Cleaning git repo" __rvm_run "$1.fetch" "git fetch origin" "Fetching from origin" fi ( remote="origin" cd "${rvm_repos_path}/${rvm_ruby_interpreter}" if [[ -z "$(git branch | awk "/$rvm_ruby_repo_branch$/")" ]] then git checkout -b "$rvm_ruby_repo_branch" \ --track "$remote/$rvm_ruby_repo_branch" 2>/dev/null elif [[ -z "$(git branch | awk "/\* $rvm_ruby_repo_branch$/")" ]] then if ! git checkout $rvm_ruby_repo_branch 2>/dev/null then rvm_error "Branch $remote/$rvm_ruby_repo_branch not found." fi fi __rvm_run "$1.pull" "git pull origin $branch" "Pulling from origin $branch" ) __rvm_fetch_from_git_revision_or_sha || return $? if [[ -n "${rvm_ruby_string}" ]] then __rvm_rm_rf "${rvm_src_path}/$rvm_ruby_string" fi __rvm_run "$1.copy" "\\cp -Rf \"${rvm_repos_path}/${rvm_ruby_interpreter}/\" \"${rvm_src_path}/$rvm_ruby_string\"" "Copying from repo to source..." builtin cd "${rvm_src_path}/$rvm_ruby_string" return ${result:-0} } __rvm_fetch_ruby() { if (( ${rvm_ruby_selected_flag:=0} == 0 )) then __rvm_select fi if (( ${rvm_head_flag:=0} == 0 )) && [[ -z "${rvm_ruby_tag:-}" && -z "${rvm_ruby_revision:-}" && -z "${rvm_ruby_sha:-}" ]] then rvm_ruby_package_name="${rvm_ruby_package_name:-"$rvm_ruby_string"}" rvm_ruby_package_file="${rvm_ruby_package_file:-"$rvm_ruby_package_name"}" case "$rvm_ruby_string" in (ruby-1.8.4*) rvm_archive_extension="${rvm_archive_extension:-tar.gz}" ;; (ruby-*) rvm_archive_extension="${rvm_archive_extension:-tar.bz2}" ;; (*) rvm_archive_extension="${rvm_archive_extension:-tar.gz}" ;; esac case "$rvm_ruby_interpreter" in (ruby) rvm_ruby_url="$(__rvm_db "${rvm_ruby_interpreter}_${rvm_ruby_release_version}.${rvm_ruby_major_version}_url")/$rvm_ruby_package_file.$rvm_archive_ext ension" ;; (ree) rvm_ruby_url="$(__rvm_db "${rvm_ruby_interpreter}_${rvm_ruby_version}_url")/${rvm_ruby_package_file}.${rvm_archive_extension}" ;; (jruby) rvm_ruby_url="$(__rvm_db "${rvm_ruby_interpreter}_url")/${rvm_ruby_version}/${rvm_ruby_package_file}.${rvm_archive_extension}" ;; (maglev) : # Should already be set from selector ;; (*) rvm_ruby_url="$(__rvm_db "${rvm_ruby_interpreter}_url")/${rvm_ruby_package_file}.${rvm_archive_extension}" ;; esac rvm_log "$rvm_ruby_string - #downloading ${rvm_ruby_package_file}, this may take a while depending on your connection..." "$rvm_scripts_path/fetch" "${rvm_ruby_url}" result=$? if (( result > 0 )) then rvm_error "There has been an error while trying to fetch the source. return $result fi \nHalting the installation." # Remove the directory if it is empty ( [[ ! -d "${rvm_src_path}/$rvm_ruby_string" ]] || rmdir "${rvm_src_path}/$rvm_ruby_string" 2>/dev/null ) || true if [[ ! -d "${rvm_src_path}/$rvm_ruby_string" ]] then mkdir -p "${rvm_tmp_path:-/tmp}/rvm_src_$$" case "$rvm_archive_extension" in tar.gz|tgz) __rvm_run "extract" \ "$rvm_tar_command xzf \"${rvm_archives_path}/$rvm_ruby_package_file.$rvm_archive_extension\" -C ${rvm_tmp_path:/tmp}/rvm_src_$$ ${rvm_tar_options:-}" \ "$rvm_ruby_string - #extracting $rvm_ruby_package_file to ${rvm_src_path}/$rvm_ruby_string" result=$? if (( result > 0 )) then rvm_error "There has been an error while trying to extract the source. return $result fi ;; zip) \nHalting the installation." __rvm_run "extract" \ "unzip -q -o ${rvm_archives_path}/$rvm_ruby_package_file -d ${rvm_tmp_path:-/tmp}/rvm_src_$$" \ "$rvm_ruby_string - #extracting $rvm_ruby_package_file to ${rvm_src_path}/$rvm_ruby_string" result=$? if (( result > 0 )) then rvm_error "There has been an error while trying to extract $rvm_ruby_package_file. \nHalting the installation." return $result fi ;; tar.bz2) __rvm_run "extract" \ "$rvm_tar_command xjf ${rvm_archives_path}/$rvm_ruby_package_file.$rvm_archive_extension -C ${rvm_tmp_path:/tmp}/rvm_src_$$ ${rvm_tar_options:-}" \ "$rvm_ruby_string - #extracting $rvm_ruby_package_file to ${rvm_src_path}/$rvm_ruby_string" result=$? if (( result > 0 )) then rvm_error "There has been an error while trying to extract the source. return $result fi ;; \nHalting the installation." *) rvm_error "Unknown archive format extension '$rvm_archive_extension'. return 1 ;; \nHalting the installation." esac __rvm_rm_rf "${rvm_src_path}/$rvm_ruby_string" mv "${rvm_tmp_path:-/tmp}/rvm_src_$$/$(builtin cd ${rvm_tmp_path:-/tmp}/rvm_src_$$ ; \ls )" \ "${rvm_src_path}/$rvm_ruby_string" __rvm_rm_rf "${rvm_tmp_path:-/tmp}/rvm_src_$$" if [[ -n "${rvm_ruby_name:-""}" && -d "${rvm_src_path}/$(echo $rvm_ruby_string | sed -e 's/-n.*//')" ]] ; then mv "${rvm_src_path}/$(echo "$rvm_ruby_string" | sed -e 's/-n.*//')" "${rvm_src_path}/$rvm_ruby_string" fi rvm_log "$rvm_ruby_string - #extracted to ${rvm_src_path}/$rvm_ruby_string" else rvm_log "$rvm_ruby_string - #extracted to ${rvm_src_path}/$rvm_ruby_string (already extracted)" fi return 0 else # -head mkdir -p "${rvm_repos_path}" true ${rvm_ruby_url:="$rvm_ruby_repo_url"} if echo "$rvm_ruby_url" | GREP_OPTIONS="" \grep 'git' >/dev/null 2>&1 then # Using a git url. case "$rvm_ruby_interpreter" in ruby) # Determine Branch if [[ -z "${rvm_ruby_repo_branch:-}" ]] then if [[ -n "${rvm_ruby_major_version:-}" ]] then if [[ -n "${rvm_ruby_minor_version:-}" ]] then rvm_ruby_repo_branch="ruby_1_${rvm_ruby_major_version}_${rvm_ruby_minor_version}" else rvm_ruby_repo_branch="ruby_1_${rvm_ruby_major_version}" fi else rvm_ruby_repo_branch="trunk" # NOTE: Ruby Core team maps 'trunk' as HEAD fi fi ;; ree|jruby|maglev|*) rvm_ruby_repo_branch="${rvm_ruby_repo_branch:-"master"}" ;; esac # Clone if repository does not yet exist locally if [[ ! -d "${rvm_repos_path}/${rvm_ruby_interpreter}/.git" ]] then __rvm_rm_rf "${rvm_repos_path}/${rvm_ruby_interpreter}" rvm_ruby_repo_http_url="${rvm_ruby_repo_url//git:/https:}" rvm_log "Cloning from $rvm_ruby_repo_url, this may take a while depending on your connection..." # do not use '--depth 1' - we need to allow getting different commits git clone "$rvm_ruby_repo_url" "${rvm_repos_path}/${rvm_ruby_interpreter}" result=$? if (( result > 0 )) then rvm_log "cloning from $rvm_ruby_repo_url failed, now attempting to clone from $rvm_ruby_repo_http_url, this may take a while depending on your connection..." git clone "$rvm_ruby_repo_http_url" \ "${rvm_repos_path}/${rvm_ruby_interpreter}" result=$? if (( result > 0 )) then rvm_error "There has been an error while trying to fetch the repository. return $result fi \nHalting the installation." fi else ( cd "${rvm_repos_path}/${rvm_ruby_interpreter}" typeset current_url current_url="$(git remote -v | awk '$1=="origin" && $3=="(fetch)" {print $2}')" [[ "$current_url" == "$rvm_ruby_repo_url" ]] || git remote set-url origin "$rvm_ruby_repo_url" ) fi # Use the selected branch. ( cd "${rvm_repos_path}/${rvm_ruby_interpreter}" remote="${remote:-origin}" branch=$(git symbolic-ref -q HEAD 2>/dev/null) branch=${branch##refs/heads/} git reset --hard HEAD # Ensure we are in a good state. git fetch "${remote}" # Download the latest updates locally. if [[ "$branch" == "${rvm_ruby_repo_branch}" ]] then git pull "${remote}" "${rvm_ruby_repo_branch}" else case "$(git branch 2>/dev/null)" in (*[[:space:]]${rvm_ruby_repo_branch}*) # Not already on the desired branch, but it does exist locally. git checkout -f "${rvm_ruby_repo_branch}" # Branch is local, checkout git pull "$remote" "${rvm_ruby_repo_branch}" # Bring local to latest ;; (*) # Desired branch does not exist locally. if git checkout -f -t "${remote}/${rvm_ruby_repo_branch}" then true else result=$? rvm_error "Branch $remote/$rvm_ruby_repo_branch not found." return $result fi ;; esac fi if [[ -n "${rvm_ruby_tag:-}" ]] then git checkout -f -q ${rvm_ruby_tag#t} ; fi return $? ) result=$? if (( result > 0 )) then rvm_error "There has been an error while checking out branch ${rvm_ruby_repo_branch}. return $result fi \nHalting the installation." __rvm_fetch_from_git_revision_or_sha || return $? else if [[ -n "${rvm_ruby_tag:-""}" ]] then # TODO: Check if tag v is valid true "${rvm_ruby_url:="$rvm_ruby_repo_url/tags/$(echo "$rvm_ruby_tag" | sed 's/^t//')"}" elif [[ -z "${rvm_ruby_version:-""}" && ${rvm_head_flag:-0} -eq 1 ]] then true "${rvm_ruby_url:="$rvm_ruby_repo_url/trunk"}" elif [[ "${rvm_ruby_major_version:-""}" == "9" ]] then if [[ -z "${rvm_ruby_minor_version:-""}" || "${rvm_ruby_minor_version:-""}" = 3 ]] then true "${rvm_ruby_url:="$rvm_ruby_repo_url/trunk"}" else true "${rvm_ruby_url:="$rvm_ruby_repo_url/branches/ruby_${rvm_ruby_release_version}_${rvm_ruby_major_version}_${rvm_ruby_minor_ve rsion}"}" fi elif [[ -z "${rvm_ruby_minor_version:-""}" || "${rvm_ruby_major_version:-""}.${rvm_ruby_minor_version:-""}" = "8.8" ]] then true "${rvm_ruby_url:="$rvm_ruby_repo_url/branches/ruby_${rvm_ruby_release_version}_${rvm_ruby_major_version}"}" else "${rvm_ruby_url:="$rvm_ruby_repo_url/branches/ruby_${rvm_ruby_release_version}_${rvm_ruby_major_version}_${rvm_ruby_minor_ve rsion}"}" fi rvm_rev="" if [[ -n "${rvm_ruby_revision:-""}" ]] then rvm_rev="-$rvm_ruby_revision" fi ( builtin cd "${rvm_repos_path}/${rvm_ruby_interpreter}" if [[ -d "${rvm_repos_path}/${rvm_ruby_interpreter}/.svn" ]] then rvm_log "Updating ruby from $rvm_ruby_url" __rvm_run "svn.switch" "svn switch $rvm_ruby_url" __rvm_run "svn.update" "svn update" if [[ -n "${rvm_rev:-""}" ]] then rvm_log "Checking out revision ${rvm_rev/-r/-r } from $rvm_ruby_url" __rvm_run "svn.checkout" "svn update -q ${rvm_rev/-r/-r }" fi else __rvm_rm_rf "${rvm_repos_path}/${rvm_ruby_interpreter}" __rvm_run "svn.checkout" \ "svn checkout -q ${rvm_rev/-r/-r } $rvm_ruby_url ${rvm_repos_path}/${rvm_ruby_interpreter}" \ "Downloading source from ${rvm_ruby_url}." fi ) result=$? if (( result > 0 )) then rvm_error "There has been an error while trying to fetch / update the source. return $result fi fi rvm_log "Copying from repo to src path..." __rvm_rm_rf "${rvm_src_path}/$rvm_ruby_string" cp -R "${rvm_repos_path}/${rvm_ruby_interpreter}" \ "${rvm_src_path}/$rvm_ruby_string" fi return ${result:-0} } __rvm_check_default() { typeset default_ruby_interpreter current_ruby_interpreter default_ruby_interpreter="$(rvm alias show default 2>/dev/null \ | awk -F"${rvm_gemset_separator:-"@"}" '{print $1}')" current_ruby_interpreter="$(echo "$rvm_ruby_string" \ | awk -F"${rvm_gemset_separator:-"@"}" '{print $1}')" if [[ -n "$current_ruby_interpreter" && "$current_ruby_interpreter" == "$default_ruby_interpreter" ]] then __rvm_run_with_env 'default.restore' 'system' \ 'rvm use system --default' 'Removing default ruby interpreter' fi return $? } __rvm_uninstall_ruby() { typeset dir if (( ${rvm_ruby_selected_flag:=0} == 0 )) then __rvm_select fi if [[ -n "${rvm_ruby_string:-""}" ]] then for dir in "$rvm_rubies_path" do if [[ -d "$dir/$rvm_ruby_string" ]] then \nHalting the installation." rvm_log "Removing $dir/$rvm_ruby_string..." __rvm_rm_rf "$dir/$rvm_ruby_string" else rvm_log "$dir/$rvm_ruby_string has already been removed." fi done if [[ -e "${rvm_bin_path}/$rvm_ruby_string" ]] then rm -f "${rvm_bin_path}/$rvm_ruby_string" fi if [[ -d "${rvm_externals_path}/$rvm_ruby_string" ]] then rvm_log "Removing ${rvm_externals_path}/$rvm_ruby_string..." __rvm_rm_rf "${rvm_externals_path}/$rvm_ruby_string" fi __rvm_remove_install_record "$rvm_ruby_string" __rvm_remove_gemsets __rvm_check_default else rvm_error "Cannot uninstall unknown package '$rvm_ruby_string'" fi unset rvm_uninstall_flag return 0 } __rvm_remove_ruby() { typeset dir if (( ${rvm_ruby_selected_flag:=0} == 0 )) then __rvm_select fi if [[ -n "${rvm_ruby_string:-""}" ]] then for dir in "${rvm_src_path}" "${rvm_rubies_path}" do if [[ -d "$dir/$rvm_ruby_string" ]] then rvm_log "Removing $dir/$rvm_ruby_string..." __rvm_rm_rf "$dir/$rvm_ruby_string" else rvm_log "it seems that $dir/$rvm_ruby_string is already non existent." fi done if [[ -e "${rvm_bin_path}/$rvm_ruby_string" ]] then rm -f "${rvm_bin_path}/$rvm_ruby_string" fi if [[ -d "${rvm_externals_path}/$rvm_ruby_string" ]] then rvm_log "Removing ${rvm_externals_path}/$rvm_ruby_string..." __rvm_rm_rf "${rvm_externals_path}/$rvm_ruby_string" fi __rvm_check_default __rvm_remove_install_record "$rvm_ruby_string" __rvm_remove_gemsets __rvm_remove_archives __rvm_remove_aliases __rvm_remove_wrappers __rvm_remove_environments __rvm_remove_binaries else rvm_error "Cannot remove unknown package '$rvm_ruby_string'" return 1 fi unset rvm_remove_flag return 0 } __rvm_reinstall_ruby() { typeset _params _params=("$@") __rvm_remove_ruby "${_params[@]}" __rvm_install_ruby "${_params[@]}" } __rvm_remove_gemsets() { typeset gemset gemsets if (( ${rvm_gems_flag:=0} == 1 )) then rvm_log "Removing $rvm_ruby_string gemsets..." gemsets=( $(find -L "${rvm_gems_path:-"$rvm_path/gems"}" -maxdepth 1 "${name_opt}" "${rvm_ruby_string}*" -type d)) for gemset in "${gemsets[@]}" do if [[ -d "$gemset" ]] then __rvm_rm_rf "$gemset" fi done fi } __rvm_remove_wrappers() { rvm_log "Removing $rvm_ruby_string wrappers..." typeset wrapper wrappers wrappers=($(find "$rvm_wrappers_path" -maxdepth 1 -mindepth 1 -type d "${name_opt}" "*$rvm_ruby_string*" 2>/dev/null)) for wrapper in "${wrappers[@]}" do __rvm_rm_rf "$wrapper" done return 0 } __rvm_remove_environments() { rvm_log "Removing $rvm_ruby_string environments..." typeset environments environment environments=($(find "$rvm_environments_path" -maxdepth 1 -mindepth 1 -type f "${name_opt}" "*$rvm_ruby_string*" )) for environment in "${environments[@]}" do if [[ -e "$environment" ]] then __rvm_rm_rf "$environment" fi done return 0 } __rvm_remove_aliases() { rvm_log "Removing $rvm_ruby_string aliases..." typeset alias_name aliases aliases=($(awk '/'$rvm_ruby_string'/' "$rvm_path/config/alias" | sed 's/=.*//')) for alias_name in "${aliases[@]}" do # Remove from alias key-value store "$rvm_scripts_path/alias" delete "$alias_name" >/dev/null 2>&1 done } __rvm_remove_archives() { if (( ${rvm_archive_flag:=0} == 1 )) then rvm_log "Removing $rvm_ruby_string archives..." rm -f ${rvm_archives_path}/${rvm_ruby_package_file}.* fi } __rvm_remove_binaries() { rvm_log "Removing $rvm_ruby_string binaries..." # Iterate over all binaries and check for symlinked wrappers etc. typeset binary_name binaries full_binary_path binaries=($(find "${rvm_bin_path}" -maxdepth 1 -mindepth 1 "${name_opt}" "*$rvm_ruby_string*" )) for full_binary_path in "${binaries[@]}" do if [[ -L "$full_binary_path" ]] && "$rvm_scripts_path/match" "$(readlink "$full_binary_path")" "$rvm_ruby_string" then rm -f "$full_binary_path" fi done ; unset binaries return 0 } __rvm_post_install() { case "$rvm_ruby_interpreter" in (jruby|ree|rbx) true ;; #skip (*) (( ${#binaries[@]} > 0 )) || binaries=(gem irb erb ri rdoc testrb rake) ;; esac if (( ${#binaries[@]} > 0 )) then rvm_log "$rvm_ruby_string - adjusting #shebangs for (${binaries[@]})." for binary in "${binaries[@]}" do if [[ -e "$rvm_ruby_home/bin/$binary" || -e "${rvm_src_path}/$rvm_ruby_string/bin/$binary" ]] then if [[ "${rvm_src_path}/$rvm_ruby_string" != "$rvm_ruby_home" && -f "${rvm_src_path}/$rvm_ruby_string/bin/$binary" ]] then cp -f "${rvm_src_path}/$rvm_ruby_string/bin/$binary" "$rvm_ruby_home/bin/$binary" elif [[ -f "$rvm_ruby_gem_home/bin/$binary" ]] then cp -f "$rvm_ruby_gem_home/bin/$binary" "$rvm_ruby_home/bin/$binary" fi __rvm_inject_gem_env "$rvm_ruby_home/bin/$binary" __rvm_inject_ruby_shebang "$rvm_ruby_home/bin/$binary" chmod +x "$rvm_ruby_home/bin/$binary" fi done fi binaries=(gem irb erb ri rdoc testrb rake) #reset # Import the initial gemsets, unless skipped. if (( ${rvm_skip_gemsets_flag:-0} == 0 )) then __rvm_run_with_env "gemsets.initial" "$rvm_ruby_string" \ "'$rvm_scripts_path/gemsets' initial" \ "$rvm_ruby_string - #importing default gemsets ($rvm_gemsets_path/)" else rvm_log "Skipped importing default gemsets" fi __rvm_irbrc __rvm_generate_default_docs } __rvm_generate_default_docs() { if [[ "$rvm_docs_flag" == "1" && "$rvm_ruby_interpreter" != "macruby" ]] then __rvm_run_with_env "docs.generate" "$rvm_ruby_string" \ "rvm docs generate-ri" "Attempting to generate ri documentation..." fi } __rvm_inject_ruby_shebang() { typeset actual_file __rvm_actual_file $1 if [[ -f "$actual_file" ]] then sed -e '1,1s=.*=#!'"/usr/bin/env ruby=" ${actual_file} > "${actual_file}.new" mv "${actual_file}.new" "${actual_file}" ; chmod +x "$actual_file" fi } __rvm_inject_gem_env() { typeset actual_file string __rvm_actual_file $1 if [[ -s "$actual_file" ]] then if [[ -n "$(head -n 1 "$actual_file" | awk '/[j]*ruby/')" ]] then string="ENV['GEM_HOME']=ENV['GEM_HOME'] || '$rvm_ruby_gem_home'\nENV['GEM_PATH']=ENV['GEM_PATH'] || '$rvm_ruby_gem_path'\nENV['PATH']='$rvm_ruby_gem_home/bin:$rvm_ruby_global_gems_path/bin:$rvm_ruby_home/bin:' + ENV['PATH']\n" elif [[ -n "$(head -n 1 "$actual_file" | awk '/bash/')" ]] then string="GEM_HOME=\${GEM_HOME:-'$rvm_ruby_gem_home'}\nGEM_PATH=\${GEM_PATH:'$rvm_ruby_gem_home:$rvm_ruby_global_gems_path'}\nPATH=$rvm_ruby_gem_home/bin:$rvm_ruby_global_gems_path/bin:$rvm_ruby_home/ bin:\$PATH\n" fi if [[ -n "$string" ]] then awk "NR==2 {print \"$string\"} {print}" "$actual_file" \ > "$actual_file.new" mv $actual_file.new $actual_file chmod +x "$actual_file" fi fi return 0 } __rvm_actual_file() { if [[ -L "$1" ]] then # If the file is a symlink, actual_file="$(readlink $1)" # read the link target so we can preserve it. else actual_file="$1" fi return 0 } __rvm_manage_rubies() { typeset manage_result bin_line manage_result=0 rvm_gemset_name="" rvm_ruby_selected_flag=0 rvm_ruby_gem_home="${rvm_ruby_gem_home:-""//${rvm_gemset_separator:-"@"}*}" rvm_ruby_string="${rvm_ruby_string:-""//${rvm_gemset_separator:-"@"}*}" # Given list of ruby strings. if [[ -n "${rubies_string:-""}" ]] then rubies=(${rubies_string//,/ }) for rvm_ruby_string in "${rubies[@]}" do current_ruby_string="$rvm_ruby_string" rvm_hook="before_install" source "$rvm_scripts_path/hook" eval "__rvm_${action}_ruby" result="$?" if (( result > 0 && manage_result == 0 )) then manage_result="$result" fi if (( result == 0 )) && [[ "$action" == "install" ]] then __rvm_record_install "$current_ruby_string" fi unset current_ruby_string __rvm_unset_ruby_variables done else # all if [[ "$action" != "install" && "$action" != "remove" && "$action" != "uninstall" ]] then typeset ruby_string while read -r ruby_string do # Keep this on second line damnit! if [[ -x "$ruby_string" ]] then rvm_ruby_string="$ruby_string" eval "__rvm_${action}_ruby" result="$?" if (( result > 0 && manage_result == 0 )) then manage_result="$result" fi # record as current_manage_string to prevent it being overridden. if (( result == 0 )) && [[ "$action" == "install" ]] then __rvm_record_install "$ruby_string" fi __rvm_unset_ruby_variables fi done < <(builtin cd "$rvm_rubies_path" ; \ find . -maxdepth 1 -mindepth 1 -type d 2> /dev/null | sed -e 's#./##g') else rvm_warn 'Really? '"$action"' all? See "rvm list known" and limit the selection to something more sane please :)' fi fi # TODO: This should return the exit status of the command that got called. return $manage_result } __rvm_record_ruby_configs() { for dir in "$rvm_path/rubies/"* do string=${dir##*/} if [[ "${string}" == default ]] ; then continue ; fi if [[ -x "${rvm_path}/rubies/${string}/bin/ruby" ]] then if [[ -s "${rvm_path}/rubies/${string}/config" ]] then continue else "${rvm_path}/rubies/${string}/bin/ruby" -rrbconfig \ -e 'File.open(RbConfig::CONFIG["prefix"] + "/config","w") { |file| RbConfig::CONFIG.each_pair{|key,value| file.write("#{key.gsub(/\.|-/,"_")}=\"#{value.gsub("$","\\$")}\"\n")} }' >/dev/null 2>&1 fi fi done } __rvm_compatibility_flag_configuration() { typeset flag flag="$1" if ! shift then rvm_error "__rvm_compability_flag_configuration requires one param." return 1 fi if [[ ${rvm_19_flag:-0} == 1 ]] then rvm_configure_flags="${rvm_configure_flags:-} ${flag}1.9" elif [[ ${rvm_18_flag:-0} == 1 ]] then rvm_configure_flags="${rvm_configure_flags:-} ${flag}1.8" fi } 1.19. hooks 1.19.1. after_use #!/usr/bin/env bash after_use_hooks=($( find -L "${rvm_path:-"$HOME/.rvm"}/hooks" -iname 'after_use_*' -type f )) for after_use_hook in "${after_use_hooks[@]}" do if [[ -x "${after_use_hook}" ]] then __rvm_conditionally_do_with_env . "${after_use_hook}" >&2 fi done 1.19.2. after_cd #!/usr/bin/env bash after_cd_hooks=($( find -L "${rvm_path:-"$HOME/.rvm"}/hooks" -iname 'after_cd_*' -type f )) for after_cd_hook in "${after_cd_hooks[@]}" do if [[ -x "${after_cd_hook}" ]] then __rvm_conditionally_do_with_env . "${after_cd_hook}" >&2 fi done 1.19.3. after_use_jruby #!/usr/bin/env bash . "${rvm_path}/scripts/functions/hooks/jruby" if [[ "${rvm_ruby_string}" =~ "jruby" ]] then jruby_ngserver_start jruby_options_append "--ng" "${PROJECT_JRUBY_OPTS[@]}" else jruby_options_remove "--ng" "${PROJECT_JRUBY_OPTS[@]}" jruby_clean_project_options fi 1.19.4. .gitkeep 1.19.5. after_cd_bundler #!/usr/bin/env bash BUNDLER_BIN_PATH="" # see BUNDLE_BIN is set in the current directories .bundle/config if grep BUNDLE_BIN .bundle/config >/dev/null 2>/dev/null then BUNDLER_BIN_PATH=$(grep BUNDLE_BIN .bundle/config | cut -d ' ' -f 2 -) # Expand the bundler stub path eval BUNDLER_BIN_PATH=$BUNDLER_BIN_PATH if [[ $path[1] == $BUNDLER_BIN_PATH ]] then # Already there echo Already on path else if [[ "${BUNDLER_BIN_PATH}" =~ "^$PWD" ]] then # Prompt the user before adding a bin directory in the current (project) directory to the path echo -n "The bundler binstubs directory is in the current directory, this may be unsafe. Are you sure you want to add it to the path(Y/N)? " trusted=0 while (( ! trusted ));do printf "%s" ' Yes or No: [y/N]? ' read response value="$(echo -n "${response}" | tr '[[:upper:]]' '[[:lower:]]' | __rvm_strip)" case "${value:-n}" in y|yes) trusted=1 ;; n|no) break ;; esac done if (( trusted )); then export PATH=$BUNDLER_BIN_PATH:$PATH export LAST_BUNDLER_BIN_PATH=$BUNDLER_BIN_PATH fi else export PATH=$BUNDLER_BIN_PATH:$PATH export LAST_BUNDLER_BIN_PATH=$BUNDLER_BIN_PATH fi fi else # There is no BUNDLE_BIN setting if [[ -n "${LAST_BUNDLER_BIN_PATH}" ]] then export PATH PATH=":${PATH}:" PATH="${PATH//:${LAST_BUNDLER_BIN_PATH}:/:}" PATH="${PATH//::/:}" PATH="${PATH#:}" PATH="${PATH%:}" fi fi 1.19.6. after_use_jruby_opts #!/usr/bin/env bash . "${rvm_path}/scripts/functions/hooks/jruby" if [[ "${rvm_ruby_string}" =~ "jruby" ]] then jruby_options_append "${PROJECT_JRUBY_OPTS[@]}" else jruby_options_remove "${PROJECT_JRUBY_OPTS[@]}" jruby_clean_project_options fi 1.19.7. after_install_codesign #!/usr/bin/env bash #################################################### # Signing compiled ruby for OSX, for details visit # # https://rvm.io/rubies/codesign/ # #################################################### # Go to subprocess so we can use returns and 'use' ruby temporarily ( # Require Mac OS [[ "$(/usr/bin/uname -s 2>/dev/null)" == Darwin ]] || return 1 # Require 10.7 - FIXME: Should be 10.7 or newer. [[ "$(/usr/bin/sw_vers -productVersion)" == 10.7* ]] || return 2 # Require rvm_codesign_identity [[ -n "${rvm_codesign_identity:-}" ]] || { rvm_warn "'rvm_codesign_identity' is not set, please set it in ~/.rvmrc" return 3 } # Require using ruby - btw this should not happen __rvm_use || { rvm_warn "can not use ruby which was just installed ... so can not sign it neither" return 4 } # Find out ruby executable to sign typeset _ruby_name _ruby_name="$(sed -n '/^ruby_install_name=/ {s/ruby_install_name="\(.*\)"/\1/; p; };' "$MY_RUBY_HOME/config" )" # Sign ruby /usr/bin/codesign -f -s "${rvm_codesign_identity}" "$(which "${_ruby_name}")" ) 1.20. man 1.20.1. man1 1.20.1.1. rvm.1 '\" t .\" Title: rvm .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/> .\" Date: 07/16/2010 .\" Manual: [FIXME: manual] .\" Source: [FIXME: source] .\" Language: English .\" .TH "RVM" "1" "07/16/2010" "[FIXME: source]" "[FIXME: manual]" .\" ----------------------------------------------------------------.\" * set default formatting .\" ----------------------------------------------------------------.\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------.\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------.SH "NAME" rvm \- The Ruby Version Manager .SH "SYNOPSIS" .sp \fBrvm\fR [\fIFLAGS\fR] [\fIOPTIONS\fR] \fIACTION\fR [\fIIMPLEMENTATION\fR[,\fIIMPLEMENTATION\fR[,\fI\&...\fR]] .SH "DESCRIPTION" .sp RVM is a command line tool which allows us to easily install, manage and work with multiple ruby environments from interpreters to sets of gems\&. .SH "FLAGS" .PP \fB\-\-head\fR .RS 4 with update, updates rvm to git head version\&. .RE .PP \fB\-\-rubygems\fR .RS 4 with update, updates rubygems for selected ruby .RE .PP \fB\-\-default\fR .RS 4 with ruby select, sets a default ruby for new shells\&. .RE .PP \fB\-\-debug\fR .RS 4 Toggle debug mode on for very verbose output\&. .RE .PP \fB\-\-trace\fR .RS 4 Toggle trace mode on to see EVERYTHING rvm is doing\&. .RE .PP \fB\-\-force\fR .RS 4 Force install, removes old install & source before install\&. .RE .PP \fB\-\-summary\fR .RS 4 Used with rubydo to print out a summary of the commands run\&. .RE .PP \fB\-\-latest\fR .RS 4 with gemset \-\-dump skips version strings for latest gem\&. .RE .PP \fB\-\-gems\fR .RS 4 with uninstall/remove removes gems with the interpreter\&. .RE .PP \fB\-\-docs\fR .RS 4 with install, attempt to generate ri after installation\&. .RE .PP \fB\-\-reconfigure\fR .RS 4 Force \&./configure on install even if Makefile already exists\&. .RE .SH "OPTIONS" .PP \fB\-v, \-\-version\fR .RS 4 Emit rvm version loaded for current shell\&. .RE .PP \fB\-l, \-\-level\fR .RS 4 patch level to use with rvm use / install .RE .PP \fB\-\-bin\fR .RS 4 path for binaries to be placed (\fI~/\&.rvm/bin/\fR) .RE .PP \fB\-\-source\fR .RS 4 src directory to use (\fI~/\&.rvm/src/\fR) .RE .PP \fB\-\-archives\fR .RS 4 directory for downladed files (\fI~/\&.rvm/archives/\fR) .RE .PP \fB\-S\fR .RS 4 Specify a script file to attempt to load and run (rubydo)\&. .RE .PP \fB\-e\fR .RS 4 Execute code from the command line\&. .RE .PP \fB\-G\fR .RS 4 root gem path to use .RE .PP \fB\-\-gems\fR .RS 4 Used to set the \fIgems_flag\fR, use with \fIremove\fR to remove gems\&. .RE .PP \fB\-\-archive\fR .RS 4 Used to set the \fIarchive_flag\fR, use with \fIremove\fR to remove archive\&. .RE .PP \fB\-\-patch\fR, \fB\-\-patches\fR .RS 4 With any ruby build from source, allows you to specify patch paths and patch names to be applied prior to building\&. Values should be a relative / absolute path to a patch or the name of known patch / patchset\&. Optionally, paths or names may be followed by \fI%someinteger\fR \- e\&.g\&. \fI\-\-patches mypatch%2\fR \- where the number following the % specifies the value of the \-p argument to patch, defaulting to two\&. .RE .PP \fB\-C, \-\-configure\fR .RS 4 custom configure options\&. If you need to pass several configure options then append them comma separated: \fI\-C \-\-\&...,\-\-\&...,\-\-\&...\fR\&. .RE .PP \fB\-\-nice\fR .RS 4 process niceness (for slow computers, default 0) .RE .PP \fB\-\-ree\-options\fR .RS 4 Options passed directly to ree\(cqs \fI\&./installer\fR on the command line\&. .RE .SH "ACTIONS" .PP \fBusage\fR .RS 4 Show this usage information\&. .RE .PP \fBversion\fR .RS 4 Show the rvm version installed in rvm_path\&. .RE .PP \fBuse\fR .RS 4 Setup current shell to use a specific ruby version\&. .RE .PP \fBreload\fR .RS 4 Reload rvm source itself (useful after changing rvm source)\&. .RE .PP \fBdo\fR .RS 4 Executes the command against either all or a listed subset of rubies. eg. rvm do gem --version ; rvm 1.8.7,1.9.2 do rake -version .RE .PP \fBenv\fR .RS 4 Displays information about an environment specified but the given ruby string\&. Useful for getting a sourceable path or an evaluatable set of shell variable declarations\&. .RE .PP \fBimplode\fR .RS 4 (seppuku) removes the rvm installation completely\&. This means everything in $rvm_path (\fI~/\&.rvm\fR)\&. This does not touch your profiles. However, this means that you must manually clean up your profiles and remove the lines which source RVM. \fIscripts/rvm\fR\&. .RE .PP \fBupdate\fR .RS 4 Upgrades rvm to the latest version\&. (If you experience bugs try this first with \-\-head)\&. .RE .PP \fBget\fR .RS 4 RVM get will 'get' the version you specify. This must be one of latest or head\&. With no arguments the rvm get help section will be shown.\&. .RE .PP \fBreset\fR .RS 4 Remove current and stored default & system settings\&. (If you experience odd behavior try this second)\&. .RE .PP \fBinfo\fR .RS 4 Show the \fBcurrent\fR environment information for current ruby\&. .RE .PP \fBdebug\fR .RS 4 Show info plus additional information for common issues\&. .RE .PP \fBinstall\fR .RS 4 Install one or many ruby versions\&. http://rvm\&.io/rubies/installing/ .RE .PP \fBuninstall\fR .RS 4 Uninstall one or many ruby versions, leaves their sources\&. .RE .PP \fBremove\fR .RS 4 Uninstall one or many ruby versions and remove their sources\&. .RE .PP \fBwrapper\fR .RS 4 Generates a set of wrapper executables for a given ruby with the specified ruby and gemset combination\&. Used under the hood for passenger support and the like\&. .RE .PP \fBruby\fR .RS 4 Runs a named ruby file against specified and/or all rubies\&. .RE .PP \fBgem\fR .RS 4 Runs a gem command using selected ruby\(cqs \fIgem\fR\&. .RE .PP \fBrake\fR .RS 4 Runs a rake task against specified and/or all rubies\&. .RE .PP \fBtests\fR .RS 4 Runs \fIrake test\fR across selected ruby versions\&. .RE .PP \fBspecs\fR .RS 4 Runs \fIrake spec\fR across selected ruby versions\&. .RE .PP \fBmonitor\fR .RS 4 Monitor cwd for testing, run \fIrake {spec,test}\fR on changes\&. .RE .PP \fBgemset\fR .RS 4 gemsets: http://rvm\&.io/gemsets/ .RE .PP \fBgemdir\fR .RS 4 Display the path to the current gem directory (\fI$GEM_HOME\fR)\&. .RE .PP \fBsrcdir\fR .RS 4 Display the path to rvm source directory (may be yanked)\&. .RE .PP \fBfetch\fR .RS 4 Performs an archive / src fetch only of the selected ruby\&. .RE .PP \fBlist\fR .RS 4 Show currently installed rubies, interactive output\&. http://rvm\&.io/rubies/list/ .RE .PP \fBpackage\fR .RS 4 Install a dependency package {readline,iconv,zlib,openssl}\&. http://rvm\&.io/packages/ .RE .PP \fBrequirements\fR .RS 4 Show additional OS specific dependencies/requirements for building various rubies. .RE .PP \fBnotes\fR .RS 4 Display notes. Operating system specifics are now under 'requirements'\&. .RE .SH "IMPLEMENTATION" .PP \fBruby\fR .RS 4 MRI/YARV Ruby (The Gold Standard) {1\&.8\&.6,1\&.8\&.7,1\&.9\&.1,1\&.9\&.2\&...} .RE .PP \fBjruby\fR .RS 4 JRuby, Ruby interpreter on the Java Virtual Machine\&. .RE .PP \fBrbx\fR .RS 4 Rubinius .RE .PP \fBree\fR .RS 4 Ruby Enterprise Edition, MRI Ruby with several custom patches for performance, stability, and memory\&. .RE .PP \fBmacruby\fR .RS 4 MacRuby, insanely fast, can make real apps (Mac OS X Only)\&. .RE .PP \fBmaglev\fR .RS 4 GemStone Ruby, awesome persistent ruby object store\&. .RE .PP \fBironruby\fR .RS 4 IronRuby, NOT supported yet\&. Looking for volunteers to help\&. .RE .PP \fBsystem\fR .RS 4 Use the system ruby (eg\&. pre\-rvm state)\&. .RE .PP \fBdefault\fR .RS 4 Use rvm set default ruby and system if it hasn\(cqt been set\&. http://rvm\&.io/rubies/default/ .RE .SH "RESOURCES" .sp Main web site .sp Online issue\-tracker .SH "COPYING" .sp Copyright (c) 2009 Wayne E\&. Seguin .sp See LICENCE file for details\&. 1.20.1.2. rvm.1.gz UnSupported Binary 1.21. vboxtest 1.21.1. test_suite.sh #!/bin/bash ############################################################################ cd "${0%/$(basename $0)}/.." RVM_PROJECT_DIR="$(pwd)" rvm_path=${RVM_PATH:-$RVM_PROJECT_DIR/rvm-test} results_file=${RESULTS_FILE:-results} messages_file=${MESSAGES_FILE:-messages} usage="usage: %s [-P RVM_PATH] [-R RESULTS_FILE] [-M MESSAGES_FILE] [-h]\n" option=" %s %s\n" while getopts "P:IR:M:h" opt do case $opt in P ) rvm_path=$OPTARG ;; R ) results_file=$OPTARG ;; M ) messages_file=$OPTARG ;; h ) printf "$usage" $0 printf "$option" "-P" "the rvm path" printf "$option" "-I" "reinstall rvm" printf "$option" "-R" "results file" printf "$option" "-M" "messages file" printf "$option" "-h" "prints this help" exit 0 ;; \? ) printf "$usage" $0 exit 2 ;; esac done shift $(($OPTIND - 1)) ############################################################################ # # RVM Setup # export RVM_PROJECT_DIR export rvm_path ./install > /dev/null # # # Run the test cases echo "Started on $(hostname)" START_TIME=$SECONDS # A portable and efficient way of running these tests with find (see # http://content.hccfl.edu/pollock/unix/findcmd.htm#exec) find "$(pwd)/vboxtest/test" -name '*_test.sh' -type f -exec sh -c ' for test_case in "$@" do "$test_case" done ' X '{}' + 2>>"$messages_file" | tee -a "$results_file" END_TIME=$SECONDS echo echo "Finished in $(($END_TIME - $START_TIME))s" if [ -f "$messages_file" ] && [ -f "$results_file" ] then # A helper function to count the number of occurrences of a character in a string. count_char () { grep -o "$1" "$2" | wc -l | tr -d " " } echo cat "$messages_file" echo "$(count_char "\." "$results_file") pass, $(count_char "F" "$results_file") fail" rm "$messages_file" "$results_file" fi 1.21.2. test_helper.sh # # # # Defines assertions and other functions needed to run the tests. flunk () { echo "[$TEST_CASE:$lineno] $TEST_NAME $1 " 1>&2 exit 1 } assert_status_equal () { expected=$1; actual=$2; lineno=$3 if [ $actual -ne $expected ] then flunk "expected exit status $expected but was $actual" fi } assert_output_equal () { expected=$(cat); actual=$1; lineno=$2 if [ "$actual" != "$expected" ] then echo "$expected" > "$0_$2_expected.txt" echo "$actual" > "$0_$2_actual.txt" flunk "unequal stdout: $(diff "$0_$2_expected.txt" "$0_$2_actual.txt")" rm "$0_$2_expected.txt" "$0_$2_actual.txt" return 1 fi } assert_equal () { assert_status_equal $1 $? $3 && assert_output_equal "$2" $3 } run_test_case () { if [ "$TEST_NAME" = "" ] then for test_name in $(grep -oE "^ *${NAME:-test_\w+} +\(\)" "$1" | tr -d " ()") do if TEST_NAME="$test_name" "$1" then printf '.' else printf 'F' fi done else "$TEST_NAME" fi } # # RVM-specific helpers # initialize_rvm () { source "$rvm_path/scripts/rvm" __rvm_cleanse_variables __rvm_load_rvmrc __rvm_initialize } 1.21.3. test 1.21.3.1. unit 1.21.3.1.1. utility_test.sh #!/usr/bin/env bash ######################################################################## TEST_CASE=$(basename "$0") ######################################################################## . ${0%/$TEST_CASE}/../../test_helper.sh initialize_rvm test_match_exits_zero_if_input_matches_the_pattern () { match "a" "a" assert_status_equal 0 $? $LINENO match "snark" "a" assert_status_equal 0 $? $LINENO match "snark" "^s" assert_status_equal 0 $? $LINENO match "snark" "k$" assert_status_equal 0 $? $LINENO match "snark" "s$" assert_status_equal 1 $? $LINENO match "snark" "^k" assert_status_equal 1 $? $LINENO match "1.9.1" "[0-9]\.[0-9]*" assert_status_equal 0 $? $LINENO match "snark.rb" "*\.rb$" assert_status_equal 0 $? $LINENO match "snark.gems" "*\.gems$" assert_status_equal 0 $? $LINENO match "snark.gem" "*\.gem$" assert_status_equal 0 $? $LINENO match "1.9.1${rvm_gemset_separator:-"@"}snark" "*${rvm_gemset_separator:-"@"}*" assert_status_equal 0 $? $LINENO match "1.9.1" "*${rvm_gemset_separator:-"@"}*" assert_status_equal 1 $? $LINENO } run_test_case "$0" 1.22. examples 1.22.1. rvmrc # # # # # # # # # Example ~/.rvmrc file. This file shows some examples of setting defaults to your own tastes. If you wish to adjust the default ruby interpreter/version/patchlevel settings they can be found in the $rvm_path/config/db file. Beware that currently that file is overwritten on install so back it up if you change anything. # rvm Path # This is where rvm installs and manages everything in by default. # #export rvm_path="$HOME/.rvm" # Source Path # This is where rvm extracts to for compiling & installing. # #export rvm_source_path="${rvm_path}/src" # Log Path # This is where rvm logs all of it's actions to # (not including the 'do' actions) # #export rvm_log_path="${rvm_path}/log" # Bin Path # This is where rvm places all of it's executable/wrapper scripts. #export rvm_bin_path="${rvm_path}/bin" # Gem Path # This is where rvm installs all gems to for each ruby # interpreter/version%gemset # #export rvm_gems_path="$rvm_path/gems" # Gem Options # These options are passed to the 'gem' command in a RVM environment. # #export rvm_gem_options="--no-rdoc --no-ri" # Temp Path # This is where rvm stores all of its temporary files. # #export rvm_tmp_path="${rvm_tmp_path:-"$rvm_path/tmp"}" # Install On Use Flag # Install rubies when used if are not installed. # # #export rvm_install_on_use_flag=1 # Gemset Create on use Flag # This will create a gemset when the gemset is used if it does not exist # # export rvm_gemset_create_on_use_flag=1 # Make Flags, I have 8 cpu's so I might use 7 make threads: # #export rvm_make_flags="-j7" # # # # # # # Source a .rvmrc file in a directory after changing to it, if it exists. To disable this fature, set in root/home .rvmrc file: export rvm_project_rvmrc=0 Or don't even bother sourcing rvm, it *is* optional. Always has been, you can instead add $rvm_path/bin to your PATH and use --default to switch... # Automatically trust project .rvmrc files # # export rvm_trust_rvmrcs_flag=1 # Always trust an rvmrc, even if it's contents change. # CAUTION: Can be dangerous / security risk. Only use this feature if you know # what you are doing / accept the implications :) # # export rvm_always_trust_rvmrc_flag # # # # # Specify RBXOPT enviroment settings that should always be set when calling Rubinius scripts. For example, to always run the agent when running from an Rubinius environment, set the value to '-Xagent' export rvm_rbx_opt # Disable automatic system configuration of RVM via /etc/profile.d/rvm.sh: # # export rvm_etc_profile_flag=0 # # Add configure flags for builds # # export rvm_configure_flags="--with-openssl-dir=$rvm_path/usr --with-readline-dir=$rvm_path/usr" # 1.23. help 1.23.1. color RVM will automatically use colors when it is possible. To overwrite use command line parameter --color=no or --color=force. It is also possible to set it with variable in ~/.rvmrc: rvm_pretty_print_flag=[no|auto|force] To change default colors use following variables in ~/.rvmrc: rvm_error_color=red rvm_warn_color=yellow rvm_debug_color=magenta rvm_notify_color=green Available colors are: black red green yellow blue magenta cyan white default You can add emphasis to the color using bold/offbold. It is also possible to change background color: bblack bred bgreen byellow bblue bmagenta bcyan bwhite bdefault On some terminals like xterm ( echo $TERM ) the bold and background colors give the same effect. Use commas to put multiple definitions in one color. You can mix color, bold and background in one definition. Specifying multiple colors/bold/background definitions will use last defined. Using bold in one definition requires resetting it in others with offbold. Using background in one definition requires resetting it in others with bdefault. Example: $ cat ~/.rvmrc rvm_error_color=bold,red rvm_warn_color=bold,yellow rvm_debug_color=offbold,magenta rvm_notify_color=offbold,green 1.23.2. implode 1.23.3. use ∴ rvm use [ruby-string] Setup current shell to use a specific ruby version. For a list of currently installed ruby string please run ∴ rvm list To create a gemset if it does not already exist: ∴ rvm --create 1.9.2@funky For creating a project .rvmrc file - From within the app's root_dir: ∴ rvm --rvmrc 1.9.2@funky Above commands can be also combined to do it all in one pass: ∴ rvm --rvmrc --create use 1.9.2@funky Using /home/mpapis/.rvm/gems/ruby-1.9.2-p290 with gemset funky Do not forget to check the generated .rvmrc file - it contains many useful comments. Note you must still 'rvm rvmrc trust' the newly created .rvmrc Please see documentation for further information: https://rvm.io/rvm/basics Also, you can combine the new flags --ruby-version and --version-conf ∴ rvm --create --ruby-version use 1.9.2@funky Using /home/mpapis/.rvm/gems/ruby-1.9.2-p290 with gemset funky ∴ rvm --create --versions-conf use 1.9.2@funky Using /home/mpapis/.rvm/gems/ruby-1.9.2-p290 with gemset funky These files do not need to be trusted, however, if a .rvmrc file exists, it will override the use of .ruby-version or .versions.conf! Please see the documentation for further information: https://rvm.io/workflow/projects#ruby-versions 1.23.4. reset 1.23.5. uninstall ∴ rvm uninstall [ruby-string[,ruby-string[,...]]] Uninstall one or many ruby versions, but leave their sources. For a list of currently installed ruby string please run rvm list Please see documentation for further information: https://rvm.io/rubies/removing/ 1.23.6. do ∴ rvm all do some-command Executes arbitrary commands against rvm set operations. If given a set that matches a single ruby command, it will exec the command directly without printing out extra rvm information. Examples: To execute 'ruby -v' against all installed rubies and aliases, you would run: ∴ rvm all do ruby -v If you want to execute it against a specific ruby (without extra logging / data printed by rvm as is done with normal set operations), you can instead do: ∴ rvm ree do ruby -v Since it is a set operation, normal ruby specifiers will work. As an example, to run it against 1.9.2 and 1.8.7 you would run: ∴ rvm 1.9.2,1.8.7 do ruby -v Or, to execute 'gem env' against all gemsets: ∴ rvm --with-rubies all-gemsets do gem env To execute 'which ruby' in the current directory, loading a .rvmrc and falling back to the default ruby: ∴ rvm --with-rubies default-with-rvmrc do which ruby For more information, refer to the rvm set operations. 1.23.7. monitor TODO 1.23.8. get Usage: rvm get {stable|latest|latest-x.y|x.y.z|head|master|branch|help} [--auto] Options: stable - install the latest RVM stable release latest - install the latest RVM release latest-x.y - install the latest RVM release matching the x.y* pattern x.y.z - install a specific RVM release head master - install the latest RVM development version --auto - automatically update shell profile files. help - Output this message. Branches: branch branch branch branch <branch> /<branch> <repo>/ <repo>/<branch> Defaults: branch: master repo: wayneeseguin Examples: rvm get branch shoes # will fetch branch shoes from wayneeseguin/rvm repo rvm get branch mpapis/ # will fetch branch master from mpapis/rvm repo 1.23.9. docs ∴ rvm docs {generate,generate-ri,generate-rdoc} Generates ri and / or rdoc documentation for the current ruby. If you have the hanna gem installed, rdoc generation should automatically use it. Alternatively, you can pass the --docs flag to automatically call 'rvm docs generate' as part of the install process. Examples: ∴ rvm docs generate Generates both ri and rdoc documentation for the current ruby. ∴ rvm docs generate-ri Generates only ri documentation for the current ruby. ∴ rvm docs generate-rdoc Generates only rdoc documentation for the current ruby. 1.23.10. cron Usage: 1. Add/Remove ruby variables to cron: rvm cron {setup|remove} 2. Manage rvm on single command level rvm cron command <"schedule"> <command> <params...> Example 1 set one ruby for all cron jobs: cd /project/dir rvm cron setup crontab -e # go to project dir, or `rvm use ...` # initialize cron with ruby settings # add tasks to cron After project ruby changes: rvm cron setup # update cron with new ruby settings Example 2 add single job using current dir for rvm: cd /project/dir # go to project dir, or `rvm use ...` rvm cron command "@daily" rake calculate:stats Refer to `man 5 crontab` for definitions of time/date, examples: "*/5 * * * *" "@hourly" "* */4 * * *" "0 6 * * *" "0 7 * * 5" - Every 5 minutes Once an hour Every 4 hours Everyday at 6am Every Friday at 7am NOTE! Do not forget to set notification email in `crontab -e`: MAILTO=someone@project.com 1.23.11. current ∴ rvm current Print the current Ruby version and the name of any gemset being used. 1.23.12. list 1.23.13. install Usage rvm install [ruby-string] For a partial list of valid ruby strings please run rvm list known For MRI Rubies you may pass configuration parameters in one of two ways: rvm install 1.9.2 --with-iconv-dir=$HOME/.rvm --without-readline and/or rvm install 1.9.2 -C --with-iconv-dir=$HOME/.rvm,--without-readline To do dirty installation using the same sources use: rvm install --force 1.9.2 To do clean installation use: rvm reinstall 1.9.2 Please see the documentation for further information: https://rvm.io/rubies/installing/ 1.23.14. ruby 'rvm ruby' Given: ∴ cat test.rb puts "patchlevel: #{RUBY_PATCHLEVEL}, release_date: #{RUBY_RELEASE_DATE}, ruby_version: #{RUBY_VERSION}, ruby_platform: #{RUBY_PLATFORM}" ∴ rvm list ruby: ruby-1.8.6-p383 [x86_64] ruby-1.8.7-p174 [x86_64] ruby-1.9.1-head [x86_64] => ruby-1.9.1-p243 [x86_64] ruby-1.9.2-preview3 [x86_64] jruby: jruby-1.3.1 [x86_64] jruby-1.4.0RC3 [x86_64] ree: ree-1.8.6-20090610 [x86_64] ree-1.8.7-20090928 [x86_64] We can run the ruby program 'test.rb' against all versions of ruby installed by RVM very simply: ∴ rvm all do ruby test.rb jruby-1.3.1: jruby 1.3.1 (ruby 1.8.6p287) (2009-06-15 2fd6c3d) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_15) [x86_64java] patchlevel: 287, release_date: 2009-06-15, ruby_version: 1.8.6, ruby_platform: java jruby-1.4.0RC3: jruby 1.4.0RC3 (ruby 1.8.7 patchlevel 174) (2009-09-30 80c263b) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_15) [x86_64-java] patchlevel: 174, release_date: 2009-09-30, ruby_version: 1.8.7, ruby_platform: java ree-1.8.6-20090610: ruby 1.8.6 (2008-08-11 patchlevel 287) [i686-darwin10.0.0] Ruby Enterprise Edition 20090610 patchlevel: 287, release_date: 2008-08-11, ruby_version: 1.8.6, ruby_platform: i686-darwin10.0.0 ree-1.8.7-20090928: ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin10.0.0], MBARI 0x6770, Ruby Enterprise Edition 20090928 patchlevel: 174, release_date: 2009-06-12, ruby_version: 1.8.7, ruby_platform: i686-darwin10.0.0 ruby-1.8.6-p383: ruby 1.8.6 (2009-08-04 patchlevel 383) [i686-darwin10.0.0] patchlevel: 383, release_date: 2009-08-04, ruby_version: 1.8.6, ruby_platform: i686-darwin10.0.0 ruby-1.8.7-p174: ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin10.0.0] patchlevel: 174, release_date: 2009-06-12, ruby_version: 1.8.7, ruby_platform: i686-darwin10.0.0 ruby-1.9.1-head: ruby 1.9.2dev (2009-09-26 trunk 25103) [x86_64-darwin10.0.0] patchlevel: -1, release_date: 2009-09-26, ruby_version: 1.9.2, ruby_platform: x86_64-darwin10.0.0 ruby-1.9.1-p243: ruby 1.9.1p243 (2009-07-16 revision 24175) [i386-darwin10.0.0] patchlevel: 243, release_date: 2009-07-16, ruby_version: 1.9.1, ruby_platform: i386-darwin10.0.0 ruby-1.9.2-preview3: ruby 1.9.2dev (2010-05-31 revision 28117) [x86_64-darwin10.3.0] patchlevel: -1, release_date: 2010-05-31, ruby_version: 1.9.2, ruby_platform: x86_64-darwin10.3.0 ree-1.8.7-20090928: ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin10.0.0], MBARI 0x6770, Ruby Enterprise Edition 20090928 patchlevel: 174, release_date: 2009-06-12, ruby_version: 1.8.7, ruby_platform: i686-darwin10.0.0 You can also restrict the above to a subset of named top level selections: ∴ rvm 1.9.1,1.8.7,jruby do ruby test.rb ... 1.23.15. srcdir 1.23.16. pkg 1.23.17. notes 1.23.18. rvmrc ∴ rvm rvmrc {trust,untrust,trusted,load,reset} [optional-path] ∴ rvm rvmrc create {ruby-version} [--rvmrc|--ruby-version|--versions-conf] Tools for dealing with and loading the rvmrc trust for a given directory. All actions take an optional path to a directory to check. Examples: To check the status of ~/My/project, you would run: ∴ rvm rvmrc trusted ~/My/project Or, more conventionally, ∴ cd ~/My/project && rvm rvmrc trusted To manually set it as trusted: ∴ rvm rvmrc trust ~/My/project Or, to reset the trust and force a prompt: ∴ rvm rvmrc reset ~/My/project ∴ rvm rvmrc reset all Finally, to load the rvmrc in a directory, you would run: ∴ rvm rvmrc load ~/My/project Or, ∴ cd ~/My/project && rvm rvmrc load Note that this replaces 'rvm load-rvmrc'. Note that load implicity trusts the rvmrc, even if it is set to untrusted. Creating project rvmrc files can easily be done with the following command: ∴ rvm --rvmrc --create use 1.9.2@funky Or for scripting, ∴ rvm rvmrc create 1.9.2@funky Above command will create both the gemset 'funky', and a project rvmrc file in the current directory. From RVM 1.11.0 new project files are available. - ∴ rvm rvmrc create 1.9.2@funky --ruby-version - ∴ rvm rvmrc create 1.9.2@funky --versions-conf - https://rvm.io/workflow/projects/#ruby-versions They do not require trusting: 1.23.19. debug Debug TODO Documentation: TODO 1.23.20. benchmark Benchmark If you have a bit of code that you would like to benchmark, across several versions of ruby all at once, you can now do this easily with RVM. Given: ∴ cat increment.rb y=0 1000.times do |x| y = x + 1 end We can benchmark this code against multiple ruby versions very easily: ∴ rvm 1.8.6,1.8.7,1.9.1,ree benchmark increment.rb Documentation: https://rvm.io/set/benchmark/ 1.23.21. migrate ∴ rvm migrate from to Efficiently moves the gems from one ruby to another. Like 'rvm gemset copy' but removes the gems from the source ruby afterwards and runs it against all gemsets for a given ruby. Examples: To migrate all gemsets from rc2 of 1.9.2 to the first release, p0, you would run: ∴ rvm migrate 1.9.2-rc2 1.9.2-p0 1.23.22. gemdir 1.23.23. alt.md # RVM is not the only Ruby enVironment Manager Other implementations allowing to switch ruby environment: - https://github.com/vertiginous/pik (Windows) https://github.com/kwatch/versionswitcher https://github.com/wilmoore/ruby-version https://github.com/sam/rb-switch https://github.com/jayferd/ry https://github.com/niw/rubies https://github.com/hmans/rbfu https://github.com/nkryptic/sandbox https://github.com/sstephenson/rbenv https://github.com/cpetschnig/switch-ruby https://github.com/mugenken/p5-Ruby-VersionManager (Perl!) http://zentest.rubyforge.org/ZenTest/Multiruby.html (Ruby) http://www.dribin.org/dave/blog/archives/2006/01/07/rails_encap/ (Tutorial) http://www.mjwall.com/2008/08/multiple-versions-of-ruby-with-stow/ (Tutorial) # RVM is not the only Ruby Version Manager Other implementations allowing to install ruby versions: - you can use your system to install ruby, most distributions come with ruby 1.8 already installed - https://github.com/vertiginous/pik (Windows) - https://github.com/kwatch/versionswitcher - https://github.com/jayferd/ry - https://github.com/sstephenson/ruby-build - https://github.com/mugenken/p5-Ruby-VersionManager (Perl!) # RVM IDE support RVM is supported by the following IDE products: - [RubyMine](http://www.jetbrains.com/ruby/) - Vim [rvm.vim](https://github.com/tpope/vim-rvm) # Editing To add a new implementation click "Edit this file" here: https://github.com/wayneeseguin/rvm/blob/master/help/alt.md 1.23.24. repair ∴ rvm repair {symlinks,environments,archives,all} Runs the repair process(es) against given parts of rvm. Examples: To regenerate all of the environment files inside your rvm/environments directory, you would run: ∴ rvm repair environments To check for stale symlinks caused by rvm in your rvm_bin_path, you would run: ∴ rvm repair symlinks To verify all downloaded archives have the correct md5, you would run: ∴ rvm repair archives Or, to do all of the above, you can run: ∴ rvm repair all 1.23.25. tests 1.23.26. info ∴ rvm info [ruby_string[,ruby_string[,...] [section,[section[,...] where sections are one of: system rvm ruby homes binaries environment debug Both ruby strings and sections are optional arguments. By default, with no parameters, rvm info will output all sections except debug. To display system rvm debug information: ∴ rvm debug which will display all sections including debug for the current or specified interpreters. Example: ∴ rvm info 1.9.2-head,1.8.7 homes,binaries,environment ruby-1.9.2-head: homes: gem: ruby: "/Users/wayne/.rvm/gems/ruby-1.9.2-head" "/Users/wayne/.rvm/rubies/ruby-1.9.2-head" binaries: ruby: irb: gem: rake: "/Users/wayne/.rvm/rubies/ruby-1.9.2-head/bin/ruby" "/Users/wayne/.rvm/rubies/ruby-1.9.2-head/bin/irb" "/Users/wayne/.rvm/rubies/ruby-1.9.2-head/bin/gem" "/Users/wayne/.rvm/gems/ruby-1.9.2-head/bin/rake" environment: GEM_HOME: GEM_PATH: MY_RUBY_HOME: IRBRC: RUBYOPT: gemset: "/Users/wayne/.rvm/gems/ruby-1.9.2-head" "/Users/wayne/.rvm/gems/ruby-1.9.2-head:/Users/wayne/.rvm/gems/ruby-1.9.2-head@global" "/Users/wayne/.rvm/rubies/ruby-1.9.2-head" "/Users/wayne/.rvm/rubies/ruby-1.9.2-head/.irbrc" "" "" ruby-1.8.7-p249: homes: gem: ruby: "/Users/wayne/.rvm/gems/ruby-1.8.7-p249" "/Users/wayne/.rvm/rubies/ruby-1.8.7-p249" binaries: ruby: irb: gem: rake: "/Users/wayne/.rvm/rubies/ruby-1.8.7-p249/bin/ruby" "/Users/wayne/.rvm/rubies/ruby-1.8.7-p249/bin/irb" "/Users/wayne/.rvm/rubies/ruby-1.8.7-p249/bin/gem" "/Users/wayne/.rvm/gems/ruby-1.8.7-p249/bin/rake" environment: GEM_HOME: GEM_PATH: MY_RUBY_HOME: IRBRC: RUBYOPT: gemset: "/Users/wayne/.rvm/gems/ruby-1.8.7-p249" "/Users/wayne/.rvm/gems/ruby-1.8.7-p249:/Users/wayne/.rvm/gems/ruby-1.8.7-p249@global" "/Users/wayne/.rvm/rubies/ruby-1.8.7-p249" "/Users/wayne/.rvm/rubies/ruby-1.8.7-p249/.irbrc" "" "" 1.23.27. remove ∴ rvm remove [ruby-string[,ruby-string[,...]]] Remove one or more rubies and their sources. For a list of currently installed rubies, please run rvm list Please see documentation for further information: https://rvm.io/rubies/removing/ 1.23.28. rubygems ∴ rvm rubygems [x.y.z|latest-x.y|latest|current|master|head] Installs a specific rubygems version in the current ruby. If 'current' is specified, the most current rubygems known to RVM will be installed. Currently only compatible with MRI 1.8.*, 1.9.* and Ruby Enterprise Edition. If your system is not supported, running the command will generate an error message. MRI 1.9.* ships with a version of RubyGems. To revert to that version after installing a custom version via 'rvm rubygems' run: 'rvm rubygems remove' The version can be also specified as latest-1.8 which will use latest available like 1.8.18 Also you could use "head" or "master" to use development version. RVM and Rubygems discourage the use of development version. Finally you can override default version with: echo "rubygems_version=latest-1.8" >> $rvm_path/user/db echo "ree_rubygems_version=latest-1.6" >> $rvm_path/user/db echo "ruby_1.9.2_p136_rubygems_version=1.3.7" >> $rvm_path/user/db 1.23.29. wrapper ∴ rvm wrapper <ruby_string> [<wrapper_prefix>|--no-prefix] [binary[ binaries[ ...]]] where ruby_string is the ruby version and gemset combination to wrap (it can also refer to a valid project path), wrapper_prefix is what to prepend to the name of the generated wrapper, and binary and binaries are the names of the binaries for which you wish to provide a wrapper (e.g. gem). When no binaries are provided, rvm will (by default) generate wrappers for ruby, gem, rake, irb, rdoc, ri, and testrb. Examples: If you wish to provide an environment-specific wrapper for rspec with a rails 3 gemset, you could do: ∴ rvm --create ree@rails3 ∴ rvm wrapper ree@rails3 r3 spec Which would add r3_spec with the specified environment to the bin directory where you installed rvm. Alternatively, if you do: ∴ rvm wrapper ruby-1.9.2-head It will create binaries named ruby, gem, rake, irb, rdoc, ri and tesrb in the rvm bin directory. Finally, to show another real and common use, you can use wrapper to generate ruby executables and gems for passenger to use. Namely: ∴ rvm use ree@rails3 --passenger is equivelant to: ∴ rvm use ree@rails3 ∴ rvm wrapper ree@rails3 passenger Which creates passenger_* binaries in the rvm bin directory using ree and the rails3 gemset. 1.23.30. specs 1.23.31. fetch Fetch Performs an archive / src fetch of the current selected ruby. Usage: ∴ rvm fetch 1.23.32. update Removed. See 'rvm help get' for updating RVM itself. 1.23.33. build Usage: rvm build <ruby_string> [options] ruby_string is of the format $interpreter-$version-$patchlevel Options: 1.23.34. disk-usage ∴ rvm disk-usage {all,archives,repos,sources,logs,packages,rubies,gemsets} Returns the amount of disk space used by a specific set of data associated with rvm. All returns each, individually, along with the total space used. Examples: To find out how much space your rvm install is using, simply run: ∴ rvm disk-usage all To find out how much space only your gemsets use, run: ∴ rvm disk-usage gemsets 1.23.35. tools ∴ rvm tools {identifier,path-identifier,strings,mirror,rvm-env} Provides generic tools related to rvm environments for gaining information about your current environment. Primarily used for scripting rvm. Examples: To get the expanded Ruby string for the current environment, you would run: ∴ rvm tools identifier To get the identifier for a folder (taking into account .rvmrc files and the like), run this instead: ∴ rvm tools path-identifier ~/path/to/directory Lastly, you can expand example Ruby strings. run: E.g., to get the current ree version, ∴ rvm tools strings ree In case of network/firewall problems, it is easy to define alternate download URLs: ∴ rvm tools mirror It is possible to use a "shebang" (#!/usr/...) line to select the interpreter (eg, Ruby 1.9.3) which processes a script file. However, this will work only on recent Linux kernels (2.6.27.9 and above). First, you need to define the shebang wrapper: ∴ rvm tools rvm-env ruby bash zsh This will define: /usr/bin/{ruby,bash,zsh}-rvm-env Your scripts can then request the proper Ruby, using shebang: #!/usr/bin/ruby-rvm-env 1.9.3 The script will be run using Ruby 1.9.3 from rvm. Alternatively, here is a hack to make a script switch itself: if !ENV['ruby_switch_flag'] ENV['ruby_switch_flag'] = '42' system('rvm', '1.9.3', 'do', __FILE__, *ARGV) exit 0 end 1.23.36. alias Alias RVM allows you to alias your rubies for your convenience and pleasure. Usage rvm [options] alias source destination Source and Destination must be an RVM ruby string representing an RVM installed ruby. A gemset may be optionally included. Creating Aliases First select an RVM ruby. ∴ rvm alias create php ree-1.8.7-p2010.01 Using Aliases Now that you have created an alias, you can use the alias in place of the longer rvm selector string. ∴ rvm use php ∴ ruby -v ruby 1.8.7 (2009-12-24 patchlevel 248) [i686-darwin10.3.0], MBARI 0x6770, Ruby Enterprise Edition 2010.01 If you use any aliases that are rather funny, please hop in #rvm and let us know :) Deleting Aliases If you wish to delete an alias ∴ rvm alias delete dotnet Listing Aliases You can also list all current aliases ∴ rvm alias list php => ree-1.8.7-p2010.01 lisp => maglev-head python => rbx-head Documentation: https://rvm.io/rubies/alias/ 1.23.37. upgrade Usage: rvm upgrade [source ruby] [destination ruby] Description: Upgrades the specified (already installed) source ruby to the given destination ruby version. Will migrate gemsets, wrappers, aliases and environment files. The process will prompt you at each stage - if the versions look incorrect, please cancel and perform it manually. Examples: $ rvm upgrade 1.9.2-p136 1.9.2-p180 $ rvm upgrade ree-2011.01 ree-2011-02 Experimental detection: $ rvm upgrade 1.9.2 Are you sure you wish to upgrade from ruby-1.9.2-p290 to ruby-1.9.2-p318? (Y/n): 1.23.38. upgrade-notes.txt * If you have any questions, issues and/or ideas for improvement please fork the project and issue a pull request. * If you wish to disable the project .rvmrc file functionality, set rvm_project_rvmrc=0 in either /etc/rvmrc or ~/.rvmrc. then log out and back in. * You _must_ read 'rvm requirements' for additional OS specific requirements for various rubies, and native-extension gems. Expect failures until those are met! * For screen users, please do not forget to read https://rvm.io/workflow/screen/. You will need to add 'shell -${SHELL}' to your $HOME/.screenrc to properly load RVM. * rvm_trust_rvmrcs has been changed to rvm_trust_rvmrcs_flag for consistency * Project rvmrc files are now checked for trust whenever they change, as promised by the note displayed during the review process * Ruby package dependency list for your OS is given by: rvm requirements * If you encounter any issues with a ruby 'X' your best bet is to: rvm get head && rvm reinstall X * If you see the following error message: Unknown alias name: 'default' re-set your default ruby, this is due to a change in how default works. * after_use and after_cd hook now supports multiple files with after_*_* the custom hooks can be easily turned on/off by: chmod +x $rvm_path/hooks/after_cd_[hook_name] chmod -x $rvm_path/hooks/after_use_[hook_name] * If your shell exits on entering a directory with freshly checked out sources you should update .rvmrc file, and replace any `exit ` with `return `. * If you wish to use RVM in an interactive fashion in other shells then place the following line at the end of your shell's loading files (.bashrc or .bash_profile for bash and .zshenv for zsh), after all PATH/variable settings: [[ -s "${rvm_scripts_path}/rvm" ]] && source "${rvm_scripts_path}/rvm" # This loads RVM into a shell session. * On some systems (like Ubuntu) rvmsudo requires following changes to work properly: http://stackoverflow.com/questions/257616/sudo-changes-path-why * To update RVM loading code append '--auto' to 'rvm get ...' * In case you have some old RVM files/rubies in '/usr/local/bin' or '$HOME/bin' feel free to remove them, they were copied there because of bug in path detection. * ZSH 4.3.15 is buggy, be careful with it, it can break RVM, especially multiuser installations, You should consider downgrading ZSH to 4.3.12 which has proven to work more reliable with RVM. * Optionally you can run \`rvm tools rvm-env ruby bash\` which will generate shebang wrappers for easier selecting ruby in scripts. * RVM comes with set of default gems including 'bundler', 'rake', 'rubygems-bundler' and 'rvm' gems, if you do not wish to get this gems install RVM with this flag: --without-gems="rvm rubygems-bundler" this option is remembered, it's enough to use it once. 1.23.39. user RVM mixed mode can be enabled on multiuser installations. To use rubies and gemsets from user home run: rvm user all To use only gemsets from user home run: rvm user gemsets It is also possible to add this settings as default for new user accounts: sudo rvm user [all|gemsets] --skel 1.23.40. reinstall Usage rvm reinstall [ruby-string] It is equivalent to: rvm remove [ruby-string] rvm install [ruby-string] Please see the documentation for further information: https://rvm.io/rubies/installing/ 1.23.41. rake Rake RVM allows you to run rake tasks across multiple ruby versions, for example: ∴ rvm all do rake spec or: ∴ rvm 1.8.6,1.9.1 do rake spec JSON Summary Add a --json flag prior to the word 'do' and a JSON summary will be printed out at the end of the run. YAML Summary Add a --yaml flag prior to the word 'do' and a YAML summary will be printed out at the end of the run. 1.23.42. cleanup ∴ rvm cleanup {all,archives,repos,sources,logs} Performs general cleanup for the specific set of rvm directories. Useful for reclaiming used disk space from rvm compiles Examples: To reclaim all of the space used by archives, repository clones, source files (and associated temporary compile file) and logs, you'd run: ∴ rvm cleanup all If instead you only wanted to clean up source files, you'd run: ∴ rvm cleanup sources Please note that sometimes having archives and sources around are desirable. Namely, you need the sources to install something such as ruby-debug under 1.9. 1.23.43. gemset Usage: rvm gemset [action] rvm --force gemset [action] Actions: import,export,create,copy,rename,empty,delete,name,dir,list,list_all,gemdir,install,pristine,clear,use,update,unpack,globalc ache Description: Commands for working with and manipulating gemsets within RVM. Any command is run in context of current ruby/gemset; call 'rvm current' to find out which is currently used. Note that 'system' supports only exporting/importing gems. Rejection: If you do not want to use gemsets and want to ignore them you can use command line flag `--ignore-gemsets`: rvm use 1.9.3@my_project --ignore-gemsets it will ignore @my_project and @global - only default gemset will be set. It can be persisted with: echo "export rvm_ignore_gemsets_flag=1" >> ~/.rvmrc 1.23.44. snapshot ∴ rvm snapshot {load,save} filename Saves or creates a snapshot of the given rvm install. This includes: * * * * * * Settings Aliases Rubies Gemsets Packages Your Default Ideally to easily maintain a consistent environment among machines / to back up your environment. Please note that this is still considered experimental to a large degree. 1.24. contrib 1.24.1. gemset_snapshot #!/usr/bin/env bash printf "\nBeginning snapshot of the current environment gem list into snapshot.gems\n" file_name="snapshot.gems" gems=($(gem list | sed 's#[\(|\)]##g' | sed 's#, #,#g' | \tr ' ' ';')) for gem in "${gems[@]}" ; do name="$(echo $gem | awk -F';' '{print $1}')" versions=($(echo $gem | awk -F';' '{print $2}' | sed 's#,# #g')) for version in "${versions[@]}" ; do echo "$name -v$version" >> "$file_name" done ; unset version versions done ; unset file_name printf "\nCompleted snapshot of the current environment gem list into snapshot.gems\n" exit $? 1.24.2. ps1_functions #!/usr/bin/env bash # # Source this file in your ~/.bash_profile or interactive startup file. # This is done like so: # # [[ -s "$HOME/.rvm/contrib/ps1_functions" ]] && # source "$HOME/.rvm/contrib/ps1_functions" # # Then in order to set your prompt you simply do the following for example # # Examples: # # ps1_set --prompt ∫ # # or # # ps1_set --prompt ∴ # # This will yield a prompt like the following, for example, # # 00:00:50 wayneeseguin@GeniusAir:~/projects/db0/rvm/rvm (git:master:156d0b4) # ∴ # ps1_titlebar() { case $TERM in (xterm*|rxvt*) printf "%s" "\033]0;\\u@\\h: \W\\007" ;; esac } ruby-1.8.7-p334@rvm ps1_identity() { if (( $UID == 0 )) ; then printf "%s" "\[\033[31m\]\\u\[\033[0m\]@\[\033[36m\]\\h\[\033[35m\]:\w\[\033[0m\] " else printf "%s" "\[\033[32m\]\\u\[\033[0m\]@\[\033[36m\]\\h\[\033[35m\]:\w\[\033[0m\] " fi } ps1_git() { local branch="" sha1="" line="" attr="" color=0 shopt -s extglob # Important, for our nice matchers :) command -v git >/dev/null 2>&1 || { printf " \033[1;37m\033[41m[git not found]\033[m " return 0 } branch=$(git symbolic-ref -q HEAD 2>/dev/null) || return 0 # Not in git repo. branch=${branch##refs/heads/} # Now we display the branch. sha1=$(git rev-parse --short --quiet HEAD) case "${branch:-"(no branch)"}" in production|prod) attr="1;37m\033[" ; color=41 ;; # red master|deploy) color=31 ;; # red stage|staging) color=33 ;; # yellow dev|develop|development) color=34 ;; # blue next) color=36 ;; # gray *) if [[ -n "${branch}" ]] ; then # Feature Branch :) color=32 # green else color=0 # reset fi ;; esac [[ $color -gt 0 ]] && printf "\[\033[${attr}${color}m\](git:${branch}$(ps1_git_status):$sha1)\[\033[0m\] " } ps1_git_status() { local git_status="$(git status 2>/dev/null)" [[ "${git_status}" = *deleted* ]] && printf "%s" "-" [[ "${git_status}" = *Untracked[[:space:]]files:* ]] && printf "%s" "+" [[ "${git_status}" = *modified:* ]] && printf "%s" "*" } ps1_rvm() { command -v rvm-prompt >/dev/null 2>&1 && printf "%s" " $(rvm-prompt) " } ps1_update() { local prompt_char='$' separator="\n" notime=0 (( $UID == 0 )) && prompt_char='#' while [[ $# -gt 0 ]] ; do local token="$1" ; shift case "$token" in --trace) export PS4="+ \${BASH_SOURCE##\${rvm_path:-}} : \${FUNCNAME[0]:+\${FUNCNAME[0]}()} set -o xtrace ;; --prompt) prompt_char="$1" shift ;; --noseparator) separator="" ;; --separator) separator="$1" shift ;; --notime) notime=1 ;; *) true # Ignore everything else. ;; esac done \${LINENO} > " if (( notime > 0 )) ; then PS1="$(ps1_titlebar)$(ps1_identity)$(ps1_git)$(ps1_rvm)${separator}${prompt_char} " else PS1="$(ps1_titlebar)\D{%H:%M:%S} $(ps1_identity)$(ps1_git)$(ps1_rvm)${separator}${prompt_char} " fi } ps2_set() { PS2=" \[\033[0;40m\]\[\033[0;33m\]> \[\033[1;37m\]\[\033[1m\]" } ps4_set() { export PS4="+ \${BASH_SOURCE##\${rvm_path:-}} : \${FUNCNAME[0]:+\${FUNCNAME[0]}()} } \${LINENO} > " # WARNING: This clobbers your PROMPT_COMMAND so if you need to write your own, call # ps1_update within your PROMPT_COMMAND with the same arguments you pass # to ps1_set # # The PROMPT_COMMAND is used to help the prompt work if the separator is not a new line. # In the event that the separtor is not a new line, the prompt line may become distored if # you add or delete a certian number of characters, making the string wider than the # $COLUMNS + len(your_input_line). # This orginally was done with callbacks within the PS1 to add in things like the git # commit, but this results in the PS1 being of an unknown width which results in the prompt # being distored if you add or remove a certain number of characters. To work around this # it now uses the PROMPT_COMMAND callback to re-set the PS1 with a known width of chracters # each time a new command is entered. see PROMPT_COMMAND for more details. # ps1_set() { PROMPT_COMMAND="ps1_update $@" } 1.24.3. bootstrap_rails_environment #!/usr/bin/env bash # # Author: Wayne E. Seguin <wayneeseguin@gmail.com> # Licence: MIT # # # This script when sourced will bootstrap a Rails development environment # on Linux and OSX # # Source this file so that it will leave you in the Sites directory. rails_version="3.0.9" ruby_version="1.9.1" sites_path="$HOME/Sites" abort=false if (( UID == 0 )) then printf "ERROR: This script may not be sourced as the root user." abort=true else if [[ ! -d "$sites_path" ]] then mkdir -p "$sites_path" fi cd "$sites_path" printf "#\n# Bootstrapping a Rails development environment!\n#\n" if [[ $MACHTYPE = *linux* ]] then printf "#\n# Ensuring OS packges are installed, you will be prompted for your password.\n#\n" if command -v apt-get then sudo apt-get install build-essential bison openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev elif command -v pacman then sudo pacman -S --noconfirm gcc patch curl bison zlib readline libxml2 libxslt git autoconf diffutils patch make elif command -v yum then sudo yum install -y gcc-c++ patch readline readline-devel zlib zlib-devel libyaml-devel libffi-devel openssl-devel sudo yum install -y iconv-devel >/dev/null 2>&1 # NOTE: For centos 5.4 final iconv-devel might not be available :( fi elif [[ $MACHTYPE = *darwin* ]] then if [[ ! -s /Library/Developer/Shared/XcodeTools.plist ]] then printf "Please Install XCode Tools before sourcing this environment bootstrap script." abort=true fi fi fi if ! $abort then printf "Ensuring that git is installed...\n" if command -v git then printf "Found git! Moving right along.\n" else printf "=> Installing Git (git command not found)" if curl -s -L -B https://rvm.io/install/git -o gitinstall then chmod +x "$PWD/gitinstall" sudo bash "$PWD/gitinstall" if [[ -f gitinstall ]] then rm -f gitinstall fi else printf "ERROR: There was an error while attempting to install git." exit 1 fi fi printf "=> Installing RVM the Ruby enVironment Manager\n https://rvm.io/rvm/install/\n" curl -s -O -L -B https://rvm.io/releases/rvm-install-head chmod +x rvm-install-head "$PWD/rvm-install-head" if [[ -f rvm-install-head ]] then rm -f rvm-install-head fi printf "=> Setting up RVM to load with new shells.\n" echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" >> "$HOME/.bash_profile" # Load RVM into a shell session *as a function*' printf "=> Loading RVM" source ~/.rvm/scripts/rvm printf "=> Installing Ruby 1.8.7\n https://rvm.io/rubies/installing/" More information about installing rubies can be found at rvm install $ruby_version printf "=> Using 1.8.7 and setting it as default for new shells\n https://rvm.io/rubies/default/\n" More information about Rubies can be found at rvm use $ruby_version --default printf "=> Installing Rails 3 to the default gemset.\n https://rvm.io/gemsets/\n" More information about gemsets can be found at gem install rails --no-rdoc --no-ri printf "=> Installing Bundler to the global gemset.\n https://rvm.io/gemsets/global/\n" rvm gemset use global gem install bundler --no-rdoc --no-ri rvm gemset clear printf "=> Installing the sqlite3 Gem.\n https://rubydoc.info/gems/sqlite3/1.3.3/frames\n" gem install sqlite3 --no-rdoc --no-ri printf " Rails development environment bootstrapped, please enjoy Rails! ~Wayne E. Seguin <wayneeseguin@gmail.com> P.S. You should now be able to generate a new Rails Application in ~/Sites with the command 'rails new <name>' " fi unset ruby_version rails_version sites_path 1.24.4. hudson 1.24.4.1. rvmRake-1.0-SNAPSHOT-20100819.hpi UnSupported Binary 1.24.4.2. README.md # RVM Hudson Plugins These plugins are forks of the ruby, rake and rubyMetrics plugins for Hudson. They're designed to make it dead simple to get started with RVM and to let you simply specify a rvm ruby string. For more current updates, see: * [http://github.com/Sutto/hudson-rvmRuby-plugin](http://github.com/Sutto/hudson-rvmRuby-plugin) * [http://github.com/Sutto/hudson-rvmRake-plugin](http://github.com/Sutto/hudson-rvmRake-plugin) * [http://github.com/Sutto/hudson-rvmRubyMetrics-plugin](http://github.com/Sutto/hudson-rvmRubyMetrics-plugin) 1.24.4.3. rvmRubyMetrics-1.0-SNAPSHOT-20100819.hpi UnSupported Binary 1.24.4.4. rvmRuby-1.0-SNAPSHOT-20100819.hpi UnSupported Binary 1.25. config 1.25.1. ssh.example Host ubuntu Port 2220 Host * HostName localhost User vboxtest UserKnownHostsFile /dev/null StrictHostKeyChecking no IdentitiesOnly yes ControlMaster auto ControlPath /tmp/socket-%r@%h:%p 1.25.2. md5 MacRuby%200.5.zip=675454a8c7bc19d606d90a726e08427c MacRuby%200.6.zip=a80afd3700c88cf95c539fc63b272faf MacRuby%200.7.1.zip=e8245dcd03c0757dfae7e6fee913947a MacRuby%200.7.zip=0bb60588c9ec9b1517665743bb05132f MacRuby%200.8.zip=735ac0a70f539e00b5de6fbec09c2c5c MacRuby%200.9.zip=fa01345e8fbfee620bbac64743a45f69 MacRuby%200.10.zip=1662d13d2f73cfc26258598f6988dcbc MacRuby%200.11.zip=b0cc23d60484a07012bcad549cef6054 MacRuby%200.12.zip=e1c5fa1b007a1cdc38c527a47302bf5e curl-7.19.7.tar.gz=ecb2e37e45c9933e2a963cabe03670ab ironruby-1.0.zip=7a92888837b3507355ed391dbfc0ab83 jruby-bin-1.3.1.tar.gz=4a95db8fc93ed7219663fbede98b6117 jruby-bin-1.4.0.tar.gz=f37322c18e9134e91e064aebb4baa4c7 jruby-bin-1.4.0.zip=3a9c8a5115a679da7d7a49a56d57d4c0 jruby-bin-1.4.1.tar.gz=a4aa8c43d1b9ffd9dbc6cb738d55a034 jruby-bin-1.4.tar.gz=54dba9a88b2b3f99ac86a79828d0178b jruby-bin-1.5.0.tar.gz=ee2b4e326e8b87858e5dd0c8e94102e6 jruby-bin-1.5.1.tar.gz=0196dcfb17354f12253eaddc1166a0ee jruby-bin-1.5.2.tar.gz=d239deb9a108a6abbfbd6cb79cf8255b jruby-bin-1.5.3.tar.gz=ccb0b2dbc300d8dd4ad1bd4da48b8320 jruby-bin-1.5.5.tar.gz=8e00f7d40cbf221f733d6f7a15784e9a jruby-bin-1.5.6.tar.gz=94033a36517645b7a7ec781a3507c654 jruby-bin-1.6.0.tar.gz=f4d7e339dfc0fbaef5b878d1c0a66fbe jruby-bin-1.6.2.tar.gz=a46f978c24a208717023bb4b8995c678 jruby-bin-1.6.3.tar.gz=694b80e4eea784cdc1eb39fb1e3132c9 jruby-bin-1.6.4.tar.gz=0e96b6f4d1c6f12b5ac480cd7ab7da78 jruby-bin-1.6.5.tar.gz=54354082673bd115f945890dc6864413 jruby-bin-1.6.5.1.tar.gz=246a7aa2b7d7e6e9e8a0c2e282cbcfd0 jruby-bin-1.6.7.tar.gz=fd1b8d7389aa92da69ea6efb4782e40a jruby-bin-1.6.7.2.tar.gz=1e520f1b5130114464e5f1950cb24774 jruby-bin-1.7.0.preview1.tar.gz=7b9e5e1cd0d818d0199086d948f948b4 libiconv-1.13.1.tar.gz=7ab33ebd26687c744a37264a330bbe9a ncurses.tar.gz=cce05daf61a64501ef6cd8da1f727ec6 openssl-0.9.8k.tar.gz=e555c6d58d276aec7fdc53363e338ab3 openssl-0.9.8n.tar.gz=076d8efc3ed93646bd01f04e23c07066 pkg-config-0.23.tar.gz=d922a88782b64441d06547632fd85744 readline-5.2.tar.gz=e39331f32ad14009b9ff49cc10c5e751 readline-6.0.tar.gz=b7f65a48add447693be6e86f04a63019 rubinius-1.0.0-20100514.tar.gz=b05f4e791d3712c5a50b3d210dac6eb0 rubinius-1.0.1-20100603.tar.gz=eb185703c7ae0c0210e8dcb7f783ee8e rubinius-1.1.0-20100923.tar.gz=e2ae16238b201de09975abe19da09ea9 rubinius-1.1.1-20101116.tar.gz=b39f618eeba37c3aff215da8bca55fd7 rubinius-1.2.0-20101221.tar.gz=4284c2660f1f648942de35d4fc871f70 rubinius-1.2.1-20110215.tar.gz=e4a5127480062fddddc7ce2860b3b813 rubinius-1.2.2-20110222.tar.gz=59124378fb7ee040e9ee4e4736d89fc0 rubinius-1.2.3-20110315.tar.gz=9782dab18c2dd440af6b76e8eb5bc0f0 rubinius-1.2.4-20110705.tar.gz=403c777d19b3553e9cb36701fe002c5e ruby-1.8.5-p115.tar.bz2=03955e3c367b9beb3efe144c9f00d689 ruby-1.8.5-p115.tar.gz=20ca6cc87eb077296806412feaac0356 ruby-1.8.5-p231.tar.bz2=327f5aa6573787432222e96195cffd1e ruby-1.8.5-p231.tar.gz=e900cf225d55414bffe878f00a85807c ruby-1.8.6-p286.tar.bz2=e6b6bf8f34370e433936adb7a7065e63 ruby-1.8.6-p286.tar.gz=797ea136fe43e4286c9362ee4516674e ruby-1.8.6-p287.tar.bz2=80b5f3db12531d36e6c81fac6d05dda9 ruby-1.8.6-p287.tar.gz=6ff3420094711266c3201a0c7c2faa38 ruby-1.8.6-p369.tar.bz2=c3c1f3dd0dfbd2e17a04e59c2f12cfc8 ruby-1.8.6-p369.tar.gz=8c140ae28b4c3947b92dfad69109d90b ruby-1.8.6-p383.tar.bz2=a48703cd982b9f0e3002700a50b0e88e ruby-1.8.6-p383.tar.gz=4f49544d4a4d0d34e9d86c41e853db2e ruby-1.8.6-p398.tar.bz2=fbd43dc44ee26be4d37e6bebbed6f8bd ruby-1.8.6-p398.tar.gz=736db5f56c2d9b0136e563d049249fa8 ruby-1.8.6-p399.tar.bz2=f77c307cb72fb8808b0e85af5d05cefc ruby-1.8.6-p399.tar.gz=c3d16cdd3c1ee8f3b7d1c399d4884e33 ruby-1.8.6-p420.tar.bz2=1c7a978e9ffd4f56dc2ad74bbd2c34f3 ruby-1.8.6-p420.tar.gz=ca1eee44f842e93b5098bc5a2bb9a40b ruby-1.8.7-p160.tar.bz2=f8ddb886b8a81cf005f53e9a9541091d ruby-1.8.7-p160.tar.gz=945398f97e2de6dd8ab6df68d10bb1a1 ruby-1.8.7-p174.tar.bz2=88c45aaf627b4404e5e4273cb03ba2ee ruby-1.8.7-p174.tar.gz=18dcdfef761a745ac7da45b61776afa5 ruby-1.8.7-p248.tar.bz2=37e19d46b7d4b845f57d3389084b94a6 ruby-1.8.7-p248.tar.gz=60a65374689ac8b90be54ca9c61c48e3 ruby-1.8.7-p249.tar.bz2=37200cc956a16996bbfd25bb4068f242 ruby-1.8.7-p249.tar.gz=d7db7763cffad279952eb7e9bbfc221c ruby-1.8.7-p299.tar.bz2=244439a87d75ab24170a9c2b451ce351 ruby-1.8.7-p299.tar.gz=43533980ee0ea57381040d4135cf9677 ruby-1.8.7-p302.tar.bz2=a6a9e37079ed8cf8726b455dad3de939 ruby-1.8.7-p302.tar.gz=a6a9e37079ed8cf8726b455dad3de939 ruby-1.8.7-p330.tar.bz2=2689719fb42c8cf0aa336f8c8933f413 ruby-1.8.7-p330.tar.gz=50a49edb787211598d08e756e733e42e ruby-1.8.7-p334.tar.bz2=2f14f604bf981bb938ab5fc8b09eb1a6 ruby-1.8.7-p334.tar.gz=aacb6ee5dfe2367682bba56af7f415b8 ruby-1.8.7-p352.tar.bz2=0c61ea41d1b1183b219b9afe97f18f52 ruby-1.8.7-p352.tar.gz=0c33f663a10a540ea65677bb755e57a7 ruby-1.8.7-p358.tar.bz2=de35f00997f4ccee3e22dff0f2d01b8a ruby-1.8.7-p370.tar.bz2=1e4c3194537dd8ff92e756993e55a29d ruby-1.9.0.tar.bz2=17eb66ac3721340d21db352d8f5dec76 ruby-1.9.1-p129.tar.bz2=6fa62b20f72da471195830dec4eb2013 ruby-1.9.1-p129.tar.gz=c71f413514ee6341c627be2957023a5c ruby-1.9.1-p243.tar.bz2=66d4f8403d13623051091347764881a0 ruby-1.9.1-p243.tar.gz=515bfd965814e718c0943abf3dde5494 ruby-1.9.1-p376.tar.bz2=e019ae9c643c5efe91be49e29781fb94 ruby-1.9.1-p376.tar.gz=ebb20550a11e7f1a2fbd6fdec2a3e0a3 ruby-1.9.1-p378.tar.bz2=5922459622a23612eb9b68a3586cb5f8 ruby-1.9.1-p378.tar.gz=9fc5941bda150ac0a33b299e1e53654c ruby-1.9.1-p429.tar.bz2=09df32ae51b6337f7a2e3b1909b26213 ruby-1.9.1-p429.tar.gz=0f6d7630f26042e00bc59875755cf879 ruby-1.9.1-p431.tar.bz2=03179138ae95dbfae872ef49e9cc6da7 ruby-1.9.1-p431.tar.gz=23f28cffc007ed5ac72c8e9bec6837ce ruby-1.9.2-p0.tar.bz2=d8a02cadf57d2571cd4250e248ea7e4b ruby-1.9.2-p0.tar.gz=755aba44607c580fddc25e7c89260460 ruby-1.9.2-p136.tar.bz2=52958d35d1b437f5d9d225690de94c13 ruby-1.9.2-p136.tar.gz=6e17b200b907244478582b7d06cd512e ruby-1.9.2-p180.tar.bz2=68510eeb7511c403b91fe5476f250538 ruby-1.9.2-p180.tar.gz=0d6953820c9918820dd916e79f4bfde8 ruby-1.9.2-p290.tar.gz=604da71839a6ae02b5b5b5e1b792d5eb ruby-1.9.2-p290.tar.bz2=096758c3e853b839dc980b183227b182 ruby-1.9.2-p318.tar.gz=cc7bf1025128e1985882ae243f348802 ruby-1.9.2-p318.tar.bz2=be431c6cbfa27e3836a06c6315717747 ruby-1.9.2-p320.tar.gz=5ef5d9c07af207710bd9c2ad1cef4b42 ruby-1.9.3-preview1.tar.bz2=7d93dc773c5824f05c6e6630d8c4bf9b ruby-1.9.3-preview1.tar.gz=0f0220be4cc7c51a82c1bd8f6a0969f3 ruby-1.9.3-preview1.tar.bz2=7d93dc773c5824f05c6e6630d8c4bf9b ruby-1.9.3-rc1.tar.bz2=26f0dc51ad981e12c58b48380112fa4d ruby-1.9.3-rc1.tar.gz=46a2a481536ca0ca0b80ad2b091df68e ruby-1.9.3-p0.tar.bz2=65401fb3194cdccd6c1175ab29b8fdb8 ruby-1.9.3-p0.tar.gz=8e2fef56185cfbaf29d0c8329fc77c05 ruby-1.9.3-p125.tar.bz2=702529a7f8417ed79f628b77d8061aa5 ruby-1.9.3-p125.tar.gz=e3ea86b9d3fc2d3ec867f66969ae3b92 ruby-1.9.3-p194.tar.bz2=2278eff4cfed3cbc0653bc73085caa34 ruby-1.9.3-p194.tar.gz=bc0c715c69da4d1d8bd57069c19f6c0e ruby-enterprise-1.8.6-20080507.tar.gz=17e3c52e73e42809f57ad0000a6cb4ab ruby-enterprise-1.8.6-20080621.tar.gz=626fc3811eee2dc92ac27ea63d37a8b2 ruby-enterprise-1.8.6-20080623.tar.gz=0bf8a3a93c6b37bb1260cc09b05e81fd ruby-enterprise-1.8.6-20080624.tar.gz=de58b97128aa65209f291c66eab7c4a7 ruby-enterprise-1.8.6-20080709.tar.gz=f0ded08cec64959fa388ec6a237b9c47 ruby-enterprise-1.8.6-20080810.tar.gz=bfdcf06f437af825cd9f2d321f9d1896 ruby-enterprise-1.8.6-20081205.tar.gz=50206bec9be2e08a862e5ec2e70fa693 ruby-enterprise-1.8.6-20081215.tar.gz=aab57b7d5061c1980bec5dbe311ec9b2 ruby-enterprise-1.8.6-20090113.tar.gz=e8d796a5bae0ec1029a88ba95c5d901d ruby-enterprise-1.8.6-20090201.tar.gz=a965e6789b553efaed72191825b13713 ruby-enterprise-1.8.6-20090421.tar.gz=c777b361aadccda7988be16ede7ab15f ruby-enterprise-1.8.6-20090520.tar.gz=156572a8296bd0440970a6bb95018a13 ruby-enterprise-1.8.6-20090610.tar.gz=0bf66ee626918464a6eccdd83c99d63a ruby-enterprise-1.8.7-2009.10.tar.gz=3727eef7b6b1b2f31db7d091328d966e ruby-enterprise-1.8.7-20090928.tar.gz=ae00018ce89d95419dfde370fcd485ac ruby-enterprise-1.8.7-2010.01.tar.gz=587aaea02c86ddbb87394a340a25e554 ruby-enterprise-1.8.7-2010.02.tar.gz=4df7b09c01adfd711b0ab76837611542 ruby-enterprise-1.8.7-2011.01.tar.gz=4640634347cd8e5469cb718853e2112e ruby-enterprise-1.8.7-2011.02.tar.gz=8c5faa11c1ddaed3f44b7294711980cc ruby-enterprise-1.8.7-2011.03.tar.gz=038604ce25349e54363c5df9cd535ec8 ruby-enterprise-1.8.7-2011.12.tar.gz=1e5f3059d52a67ab5d91d472b756de08 ruby-enterprise-1.8.7-2012.02.tar.gz=8d086d2fe68a4c57ba76228e97fb3116 rubygems-0.4.0.tgz=86a64616548a793e1a5f825f0dd385b9 rubygems-0.5.0.tgz=80d151edd94a06bcd2452a7e272b4d96 rubygems-0.6.0.tgz=5df803f5a04654833690dd32283de741 rubygems-0.6.1.tgz=c4a0faa9f876ad805ae80d1396a29d97 rubygems-0.7.0.tgz=ede9b55343219e8b3491793aa12c46f3 rubygems-0.8.0.tgz=9ef6e3c34dcb54e295c8e57321ddc079 rubygems-0.8.1.tgz=6276d268b420c0d61796cdbf6d28dae4 rubygems-0.8.10.tgz=d26592e280c0fb24c51f2837c3f48e67 rubygems-0.8.11.tgz=aa363b428c4c1fc2e076a4ff77b957d7 rubygems-0.8.3.tgz=6e6da80f61d6e77d0ad9e531767f6fd5 rubygems-0.8.4.tgz=a2ad2d03dae8a98002c2a7cd6c3ed352 rubygems-0.8.5.tgz=b917c084e1e6e99d8e102af8dd687ddb rubygems-0.8.6.tgz=9de98d2f62e3f91521b0207a4dcdeb5b rubygems-0.8.7.tgz=7fc04b9f9acc0c18cbbe6222be8d0bd3 rubygems-0.8.8.tgz=a8535e9c35a4c215d6ef9268d4bc69ed rubygems-0.9.0.tgz=5d496e1f415b8b4033ab867f01d1161f rubygems-0.9.1.tgz=a62314cdb174ccc88a27b8924fa79e4a rubygems-0.9.2.tgz=cc525053dd465ab6e33af382166fa808 rubygems-0.9.3.tgz=600940a22ecd79e28e0fd37ad1f1d871 rubygems-0.9.4.tgz=b5680acaa019c80ea44fe87cc2e227da rubygems-0.9.5.tgz=91f7036a724e34cc66dd8d09348733d9 rubygems-1.0.0.tgz=b0b74eac0cbfc5a13f895ab6f803edc1 rubygems-1.0.1.tgz=0d5851084955c327ee1dc9cbd631aa5f rubygems-1.1.0.tgz=85f994904c5b4045f0a859b29d0be717 rubygems-1.1.1.tgz=1a77c5b6b293a3ccd5261dc120641ccc rubygems-1.2.0.tgz=b77a4234360735174d1692e6fc598402 rubygems-1.3.0.tgz=63d3dfc038710eaf532b6a133225115a rubygems-1.3.1.tgz=a04ee6f6897077c5b75f5fd1e134c5a9 rubygems-1.3.2.tgz=6204d0a4c526a1d8fdbce746647b179a rubygems-1.3.3.tgz=0e9697db44d812712350baf28016b4a7 rubygems-1.3.4.tgz=b17b398503253bf36a101c58f02a226f rubygems-1.3.5.tgz=6e317335898e73beab15623cdd5f8cff rubygems-1.3.6.tgz=789ca8e9ad1d4d3fe5f0534fcc038a0d rubygems-1.3.7.tgz=e85cfadd025ff6ab689375adbf344bbe rubygems-1.4.1.tgz=e915dbf79e22249d10c0fcf503a5adda rubygems-1.4.2.tgz=b5badb7c5adda38d9866fa21ae46bbcc rubygems-1.5.0.tgz=49bef7186bf3c0ca6ee7adf4b585bccc rubygems-1.5.1.tgz=47577a5e33c9c6f1e3a56aff7f51d0ff rubygems-1.5.2.tgz=3951f94c09c16c774c8bcebc94fa5374 rubygems-1.5.3.tgz=38bbbdc17aef923fb41f054cf8421116 rubygems-1.6.0.tgz=abd27b5a9002100ff74ddb398a1c9689 rubygems-1.6.1.tgz=a77c64896aaa10d64aaf34f5c1488173 rubygems-1.6.2.tgz=0c95a9869914ba1a45bf71d3b8048420 rubygems-1.8.6.tgz=8e95d0c5b377a003f3d54a49461e81d9 rubygems-1.8.9.tgz=fc399445d693c29778779e5828ee5e90 rubygems-1.8.10.tgz=5b08ee31740c9b0bd36f6c04d537e7d4 zlib-1.2.3.tar.gz=debc62758716a169df9f62e6ab2bc634 zlib-1.2.5.tar.gz=c735eab2d659a96e5a594c9e8541ad63 yaml-0.1.4.tar.gz=36c852831d02cf90508c29852361d01b GemStone-27184.Darwin-i386.tar.gz=292b3b169656a8451cfa19c228828e5a GemStone-27184.Linux-x86_64.tar.gz=cfabd4dd73d2656fc10243e35dd7452b GemStone-27184.SunOS-i86pc.tar.gz=5755a0689488748dfeab3bc74572aaa8 MagLev-1.0.0.tar.gz=e02cb8ee04438451eb78df14f91a68a9 ruby-1.9.2-p320.tar.bz2=b226dfe95d92750ee7163e899b33af00 rubygems-1.8.23.tgz=178b0ebae78dbb46963c51ad29bb6bd9 1.25.3. known # MRI Rubies [ruby-]1.8.6[-p420] [ruby-]1.8.7[-p370] [ruby-]1.9.1[-p431] [ruby-]1.9.2-p180 [ruby-]1.9.2-p290 [ruby-]1.9.2-p318 [ruby-]1.9.2[-p320] [ruby-]1.9.2-head [ruby-]1.9.3-preview1 [ruby-]1.9.3-rc1 [ruby-]1.9.3-p0 [ruby-]1.9.3-p125 [ruby-]1.9.3[-p194] [ruby-]1.9.3-head ruby-head # GoRuby goruby # TheCodeShop - MRI experimental patches tcs # JRuby jruby-1.2.0 jruby-1.3.1 jruby-1.4.0 jruby-1.6.5 jruby-1.6.5.1 jruby-1.6.6 jruby-1.6.7 jruby[-1.6.7.2] jruby-head jruby-1.7.0.preview1 # Rubinius rbx-1.0.1 rbx-1.1.1 rbx-1.2.3 rbx-1.2.4 rbx[-head] rbx-2.0.testing # Ruby Enterprise Edition ree-1.8.6 ree[-1.8.7][-2012.02] # Kiji kiji # MagLev maglev[-head] maglev-1.0.0 # Mac OS X Snow Leopard Or Newer macruby-0.10 macruby-0.11 macruby[-0.12] macruby-nightly macruby-head # IronRuby -- Not implemented yet. ironruby-0.9.3 ironruby-1.0-rc2 ironruby-head 1.25.4. db #General niceness=0 # Rubies interpreter=ruby ruby_version=1.9.3 ruby_configure_flags=--enable-shared --disable-install-doc ruby_patchlevel=194 ruby_configure=--enable-shared tcs_repo_url=git://github.com/thecodeshop/ruby.git tcs_repo_branch=trunk ruby_repo_url=git://github.com/ruby/ruby.git ruby_1.0_url=http://ftp.ruby-lang.org/pub/ruby/1.0 ruby_1.2_url=http://ftp.ruby-lang.org/pub/ruby/1.2 ruby_1.3_url=http://ftp.ruby-lang.org/pub/ruby/1.3 ruby_1.4_url=http://ftp.ruby-lang.org/pub/ruby/1.4 ruby_1.5_url=http://ftp.ruby-lang.org/pub/ruby/1.5 ruby_1.6_url=http://ftp.ruby-lang.org/pub/ruby/1.6 ruby_1.7_url=http://ftp.ruby-lang.org/pub/ruby/1.7 ruby_1.8_url=http://ftp.ruby-lang.org/pub/ruby/1.8 ruby_1.9_url=http://ftp.ruby-lang.org/pub/ruby/1.9 ruby_2.0_url=http://ftp.ruby-lang.org/pub/ruby/2.0 ruby_1.9.3_patch_level=194 ruby_1.9.2_patch_level=320 ruby_1.9.1_patch_level=431 ruby_1.8.7_patch_level=370 ruby_1.8.6_patch_level=420 ruby_1.8.5_patch_level=231 rubygems_url=http://production.cf.rubygems.org/rubygems rubygems_repo_url=git://github.com/rubygems/rubygems.git rubygems_version=latest-1.8 # ruby_1.9.3_head_rubygems_version=1.8.5 rbx_version=head rbx_1.0.0_patch_level=20100514 rbx_1.0.1_patch_level=20100603 rbx_1.1.0_patch_level=20100923 rbx_1.1.1_patch_level=20101116 rbx_1.2.0_patch_level=20101221 rbx_1.2.1_patch_level=20110215 rbx_1.2.2_patch_level=20110222 rbx_1.2.3_patch_level=20110315 rbx_1.2.4_patch_level=20110705 rbx_url=http://asset.rubini.us rubinius_repo_url=git://github.com/rubinius/rubinius.git ree_version=1.8.7 ree_configure_flags=--dont-install-useful-gems --no-dev-docs ree_1.8.6_patch_level=20090610 ree_1.8.6_url=http://rubyforge.org/frs/download.php/58677 ree_1.8.6_repo_url=git://github.com/FooBarWidget/rubyenterpriseedition.git ree_1.8.7_url=http://rubyenterpriseedition.googlecode.com/files ree_1.8.7_repo_url=git://github.com/FooBarWidget/rubyenterpriseedition187-330 ree_1.8.7_patch_level=2012.02 ree_1.8.7_2010.02_url=http://rubyforge.org/frs/download.php/71096 kiji_repo_url=git://github.com/twitter/rubyenterpriseedition187-248.git kiji_version=head jruby_version=1.6.7.2 jruby_repo_url=git://github.com/jruby/jruby.git jruby_url=http://jruby.org.s3.amazonaws.com/downloads macruby_version=0.12 macruby_nightly_version=0.13 macruby_0.10_url=http://macruby.macosforge.org/files macruby_url=https://github.com/downloads/MacRuby/MacRuby macruby_repo_url=git://github.com/MacRuby/MacRuby.git macruby_nightly_url=http://macruby.macosforge.org/files/nightlies/macruby_nightly-latest.pkg maglev_version=head maglev_url=http://glass-downloads.gemstone.com/maglev maglev_repo_url=git://github.com/MagLev/maglev.git ironruby_version=1.0 ironruby_repo_url=git://github.com/ironruby/ironruby.git ironruby_1.0_url=http://rubyforge.org/frs/download.php/70179/ # Packages readline_url=http://ftp.gnu.org/gnu/readline libiconv_url=http://ftp.gnu.org/pub/gnu/libiconv curl_url=http://curl.haxx.se/download openssl_url=http://www.openssl.org/source openssl_version=1.0.1c zlib_url=http://prdownloads.sourceforge.net/libpng autoconf_url=http://ftp.gnu.org/gnu/autoconf ncurses_url=http://ftp.gnu.org/pub/gnu/ncurses pkg-config_url=http://pkgconfig.freedesktop.org/releases gettext_url=http://ftp.gnu.org/pub/gnu/gettext libxml2_url=ftp://xmlsoft.org/libxml2 libxslt_url=ftp://xmlsoft.org/libxslt yaml_url=https://rvm.io/src glib_url=http://ftp.gnome.org/pub/gnome/sources/glib/2.23 mono_url=http://ftp.novell.com/pub/mono/sources/mono llvm_url=https://llvm.org/svn/llvm-project/llvm/trunk 1.26. patches 1.26.1. readline-6.2 1.26.1.1. patch-shobj-conf.diff --- support/shobj-conf.orig2009-10-29 00:20:21.000000000 +1100 +++ support/shobj-conf2011-03-24 13:43:03.000000000 +1100 @@ -157,19 +157,19 @@ ;; # Darwin/MacOS X -darwin[89]*|darwin10*) +darwin[89]*|darwin1[0-9]*) SHOBJ_STATUS=supported SHLIB_STATUS=supported SHOBJ_CFLAGS='-fno-common' -SHOBJ_LD='MACOSX_DEPLOYMENT_TARGET=10.3 ${CC}' +SHOBJ_LD='${CC}' SHLIB_LIBVERSION='$(SHLIB_MAJOR)$(SHLIB_MINOR).$(SHLIB_LIBSUFF)' SHLIB_LIBSUFF='dylib' -SHOBJ_LDFLAGS='-dynamiclib -dynamic -undefined dynamic_lookup -arch_only `/usr/bin/arch`' -SHLIB_XLDFLAGS='-dynamiclib -arch_only `/usr/bin/arch` -install_name $(libdir)/$@ -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR) -v' +SHOBJ_LDFLAGS='-dynamiclib -dynamic -undefined dynamic_lookup' +SHLIB_XLDFLAGS='-dynamiclib -install_name $(libdir)/$@ -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR) -v' SHLIB_LIBS='-lncurses'# see if -lcurses works on MacOS X 10.1 ;; @@ -186,11 +186,11 @@ SHLIB_LIBSUFF='dylib' case "${host_os}" in -darwin[789]*|darwin10*)SHOBJ_LDFLAGS='' -SHLIB_XLDFLAGS='-dynamiclib -arch_only `/usr/bin/arch` -install_name $(libdir)/$@ -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR) -v' +darwin[789]*|darwin1[0-9]*)SHOBJ_LDFLAGS='' +SHLIB_XLDFLAGS='-dynamiclib -install_name $(libdir)/$@ -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR) -v' ;; *)SHOBJ_LDFLAGS='-dynamic' -SHLIB_XLDFLAGS='-arch_only `/usr/bin/arch` -install_name $(libdir)/$@ -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) compatibility_version $(SHLIB_MAJOR) -v' +SHLIB_XLDFLAGS='-install_name $(libdir)/$@ -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR) -v' ;; esac 1.26.2. goruby 1.26.2.1. support_joke.patch --- a/vm_opts.h +++ b/vm_opts.h @@ -46,6 +46,6 @@ #define OPT_STACK_CACHING 0 /* misc */ -#define SUPPORT_JOKE +#define SUPPORT_JOKE 0 1 #endif /* RUBY_VM_OPTS_H */ 1.26.3. ree 1.26.3.1. lib64.patch --- a/installer.rb +++ b/installer.rb @@ -281,7 +281,7 @@ if install_autoconf_package('source', 'Ruby Enterprise Edition') # Some installed files may have wrong permissions # (not world-readable). So we fix this. -if sh("chmod -R g+r,o+r,o-w #{@destdir}#{@prefix}/lib/ruby") +if sh("chmod -R g+r,o+r,o-w #{@destdir}#{@prefix}/lib*/ruby") if @using_system_allocator_library && !sh("install source/libsystem_allocator.dylib #{@destdir}#{@prefix}/lib/") return false @@ -307,7 +307,7 @@ def install_rubygems # We might be installing into a fakeroot, so add the fakeroot's library # search paths to RUBYLIB so that gem installation will work. -basedir = "#{@destdir}#{@prefix}/lib/ruby" +basedir = "#{@destdir}#{@prefix}/lib*/ruby" libdir = "#{basedir}/1.8" archname = File.basename(File.dirname(Dir["#{libdir}/*/thread.#{PlatformInfo::RUBYLIBEXT}"].first)) extlibdir = "#{libdir}/#{archname}" 1.26.3.2. fix-irb-completion.diff diff --git a/lib/irb/completion.rb b/lib/irb/completion.rb index 000658e..609dca3 100644 --- a/lib/irb/completion.rb +++ b/lib/irb/completion.rb @@ -157,7 +157,7 @@ module IRB end next if name != "IRB::Context" and /^(IRB|SLex|RubyLex|RubyToken)/ =~ name candidates.concat m.instance_methods(false) + candidates.concat m.instance_methods(false).map { |m| m.to_s } } candidates.sort! candidates.uniq! 1.26.3.3. 1.8.7 1.26.3.3.1. no_sslv2.diff Index: ossl_ssl.c =================================================================== --- a/ext/openssl/ossl_ssl.c(revision 32381) +++ b/ext/openssl/ossl_ssl.c(revision 32382) @@ -107,9 +107,12 @@ OSSL_SSL_METHOD_ENTRY(TLSv1), OSSL_SSL_METHOD_ENTRY(TLSv1_server), OSSL_SSL_METHOD_ENTRY(TLSv1_client), +#if defined(HAVE_SSLV2_METHOD) && defined(HAVE_SSLV2_SERVER_METHOD) && \ + defined(HAVE_SSLV2_CLIENT_METHOD) OSSL_SSL_METHOD_ENTRY(SSLv2), OSSL_SSL_METHOD_ENTRY(SSLv2_server), OSSL_SSL_METHOD_ENTRY(SSLv2_client), +#endif OSSL_SSL_METHOD_ENTRY(SSLv3), OSSL_SSL_METHOD_ENTRY(SSLv3_server), OSSL_SSL_METHOD_ENTRY(SSLv3_client), 1.26.3.3.2. tcmalloc.patch diff --git a/distro/google-perftools-1.7/src/tcmalloc.cc b/distro/google-perftools-1.7/src/tcmalloc.cc index 8d94d20..0769425 100644 --- a/distro/google-perftools-1.7/src/tcmalloc.cc +++ b/distro/google-perftools-1.7/src/tcmalloc.cc @@ -137,6 +137,13 @@ # define WIN32_DO_PATCHING 1 #endif +// GLibc 2.14+ requires the hook functions be declared volatile, based on the value of the +// define __MALLOC_HOOK_VOLATILE. For compatibility with older/non-GLibc implementations, +// provide an empty definition. +#if !defined(__MALLOC_HOOK_VOLATILE) +#define __MALLOC_HOOK_VOLATILE +#endif + using STL_NAMESPACE::max; using STL_NAMESPACE::numeric_limits; using STL_NAMESPACE::vector; @@ -1669,5 +1676,5 @@ static void *MemalignOverride(size_t align, size_t size, const void *caller) MallocHook::InvokeNewHook(result, size); return result; } -void *(*__memalign_hook)(size_t, size_t, const void *) = MemalignOverride; +void *(*__MALLOC_HOOK_VOLATILE __memalign_hook)(size_t, size_t, const void *) = MemalignOverride; #endif // #ifndef TCMALLOC_FOR_DEBUGALLOCATION 1.26.3.3.3. stdout-rouge-fix.patch diff --git a/lib/mkmf.rb b/lib/mkmf.rb index c9e738a..7a8004d 100644 --- a/lib/mkmf.rb +++ b/lib/mkmf.rb @@ -201,20 +201,26 @@ end module Logging @log = nil @logfile = 'mkmf.log' - @orgerr = $stderr.dup - @orgout = $stdout.dup @postpone = 0 @quiet = $extmk + + + + + + + + + + def self::open @log ||= File::open(@logfile, 'w') @log.sync = true orgerr = $stderr.dup orgout = $stdout.dup $stderr.reopen(@log) $stdout.reopen(@log) yield ensure $stderr.reopen(@orgerr) $stdout.reopen(@orgout) if orgerr $stderr.reopen(orgerr) orgerr.close end if orgout $stdout.reopen(orgout) orgout.close end end def self::message(*s) 1.26.3.3.4. zlib-gc-fix.diff ../../ruby/1.8.7/zlib-gc-fix.diff 1.26.3.3.5. readline-fix.diff ../../ruby/1.8.7/readline-fix.diff 1.26.3.3.6. 2010.02 1.26.3.3.6.1. tcmalloc.patch diff --git a/distro/google-perftools-1.4/src/tcmalloc.cc b/distro/google-perftools-1.4/src/tcmalloc.cc index 8d94d20..0769425 100644 --- a/distro/google-perftools-1.4/src/tcmalloc.cc +++ b/distro/google-perftools-1.4/src/tcmalloc.cc @@ -137,6 +137,13 @@ # define WIN32_DO_PATCHING 1 #endif +// GLibc 2.14+ requires the hook functions be declared volatile, based on the value of the +// define __MALLOC_HOOK_VOLATILE. For compatibility with older/non-GLibc implementations, +// provide an empty definition. +#if !defined(__MALLOC_HOOK_VOLATILE) +#define __MALLOC_HOOK_VOLATILE +#endif + using STL_NAMESPACE::max; using STL_NAMESPACE::numeric_limits; using STL_NAMESPACE::vector; @@ -1669,5 +1676,5 @@ static void *MemalignOverride(size_t align, size_t size, const void *caller) MallocHook::InvokeNewHook(result, size); return result; } -void *(*__memalign_hook)(size_t, size_t, const void *) = MemalignOverride; +void *(*__MALLOC_HOOK_VOLATILE __memalign_hook)(size_t, size_t, const void *) = MemalignOverride; #endif // #ifndef TCMALLOC_FOR_DEBUGALLOCATION 1.26.3.4. 1.8.6 1.26.3.4.1. no_sslv2.diff Index: ossl_ssl.c =================================================================== --- a/ext/openssl/ossl_ssl.c(revision 32381) +++ b/ext/openssl/ossl_ssl.c(revision 32382) @@ -107,9 +107,12 @@ OSSL_SSL_METHOD_ENTRY(TLSv1), OSSL_SSL_METHOD_ENTRY(TLSv1_server), OSSL_SSL_METHOD_ENTRY(TLSv1_client), +#if defined(HAVE_SSLV2_METHOD) && defined(HAVE_SSLV2_SERVER_METHOD) && \ + defined(HAVE_SSLV2_CLIENT_METHOD) OSSL_SSL_METHOD_ENTRY(SSLv2), OSSL_SSL_METHOD_ENTRY(SSLv2_server), OSSL_SSL_METHOD_ENTRY(SSLv2_client), +#endif OSSL_SSL_METHOD_ENTRY(SSLv3), OSSL_SSL_METHOD_ENTRY(SSLv3_server), OSSL_SSL_METHOD_ENTRY(SSLv3_client), 1.26.3.4.2. tcmalloc.patch --- a/vendor/google-perftools-1.2/src/tcmalloc.cc +++ b/vendor/google-perftools-1.2/src/tcmalloc.cc @@ -137,6 +137,13 @@ # define WIN32_DO_PATCHING 1 #endif 2011-02-24 02:09:12.000000000 -0800 2011-11-11 12:46:13.704738476 -0800 +// GLibc 2.14+ requires the hook functions be declared volatile, based on the value of the +// define __MALLOC_HOOK_VOLATILE. For compatibility with older/non-GLibc implementations, +// provide an empty definition. +#if !defined(__MALLOC_HOOK_VOLATILE) +#define __MALLOC_HOOK_VOLATILE +#endif + using STL_NAMESPACE::max; using STL_NAMESPACE::numeric_limits; using STL_NAMESPACE::vector; @@ -1669,5 +1676,5 @@ static void *MemalignOverride(size_t align, size_t size, const void *caller) MallocHook::InvokeNewHook(result, size); return result; } -void *(*__memalign_hook)(size_t, size_t, const void *) = MemalignOverride; +void *(*__MALLOC_HOOK_VOLATILE __memalign_hook)(size_t, size_t, const void *) = MemalignOverride; #endif // #ifndef TCMALLOC_FOR_DEBUGALLOCATION 1.26.3.4.3. perftools-gcc46.patch --- a/vendor/google-perftools-1.2/src/system-alloc.cc2011-11-11 20:31:45.809796278 -0800 +++ b/vendor/google-perftools-1.2/src/system-alloc.cc2011-11-11 20:33:00.067244007 -0800 @@ -31,6 +31,7 @@ // Author: Sanjay Ghemawat #include "config.h" +#include <stddef.h> #if defined HAVE_STDINT_H #include <stdint.h> #elif defined HAVE_INTTYPES_H 1.26.3.4.4. stdout-rouge-fix.patch --- a/lib/mkmf.rb2009-06-10 09:09:22.000000000 +0200 +++ b/lib/mkmf.rb2011-11-12 02:53:05.862766935 +0100 @@ -168,19 +168,25 @@ module Logging @log = nil @logfile = 'mkmf.log' - @orgerr = $stderr.dup - @orgout = $stdout.dup @postpone = 0 + + + + + + + + + + def self::open @log ||= File::open(@logfile, 'w') @log.sync = true orgerr = $stderr.dup orgout = $stdout.dup $stderr.reopen(@log) $stdout.reopen(@log) yield ensure $stderr.reopen(@orgerr) $stdout.reopen(@orgout) if orgerr $stderr.reopen(orgerr) orgerr.close end if orgout $stdout.reopen(orgout) orgout.close end end def self::message(*s) 1.26.3.4.5. openssl-1.0.patch From 46b84175dfac14a92fd6bcf3b03bc3c3715ab6cb Mon Sep 17 00:00:00 2001 From: nahi <nahi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> Date: Sat, 6 Mar 2010 21:47:30 +0000 Subject: [PATCH] backport the commit from trunk: Sun Feb 28 11:49:35 2010 NARUSE, Yui <naruse@ruby-lang.org> * openssl/ossl.c (OSSL_IMPL_SK2ARY): for OpenSSL 1.0. patched by Jeroen van Meeuwen at [ruby-core:25210] fixed by Nobuyoshi Nakada [ruby-core:25238], Hongli Lai [ruby-core:27417], and Motohiro KOSAKI [ruby-core:28063] * ext/openssl/ossl_ssl.c (ossl_ssl_method_tab), (ossl_ssl_cipher_to_ary): constified. * ext/openssl/ossl_pkcs7.c (pkcs7_get_certs, pkcs7_get_crls): split pkcs7_get_certs_or_crls. git-svn-id: http://svn.ruby-lang.org/repos/ruby/branches/ruby_1_8@26838 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --ext/openssl/ossl.c | 6 +++--ext/openssl/ossl.h | 7 +++++++ ext/openssl/ossl_pkcs7.c | 40 ++++++++++++++++++++++++++++++---------ext/openssl/ossl_ssl.c | 4 ++-ext/openssl/ossl_x509attr.c | 5 +++-ext/openssl/ossl_x509crl.c | 4 ++-6 files changed, 47 insertions(+), 19 deletions(-) diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c index d4a2dc1..85ba654 100644 --- a/ext/openssl/ossl.c +++ b/ext/openssl/ossl.c @@ -92,7 +92,7 @@ ossl_x509_ary2sk(VALUE ary) #define OSSL_IMPL_SK2ARY(name, type) \ VALUE\ -ossl_##name##_sk2ary(STACK *sk)\ +ossl_##name##_sk2ary(STACK_OF(type) *sk)\ {\ type *t;\ int i, num;\ @@ -102,7 +102,7 @@ ossl_##name##_sk2ary(STACK *sk)\ OSSL_Debug("empty sk!");\ return Qnil;\ }\ num = sk_num(sk);\ + num = sk_##type##_num(sk);\ if (num < 0) {\ OSSL_Debug("items in sk < -1???");\ return rb_ary_new();\ @@ -110,7 +110,7 @@ ossl_##name##_sk2ary(STACK *sk)\ ary = rb_ary_new2(num);\ \ for (i=0; i<num; i++) {\ -t = (type *)sk_value(sk, i);\ +t = sk_##type##_value(sk, i);\ rb_ary_push(ary, ossl_##name##_new(t));\ }\ return ary;\ diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h index 9215dc4..d0edb7d 100644 --- a/ext/openssl/ossl.h +++ b/ext/openssl/ossl.h @@ -108,6 +108,13 @@ extern VALUE eOSSLError; } while (0) /* + * Compatibility + */ +#if OPENSSL_VERSION_NUMBER >= 0x10000000L +#define STACK _STACK +#endif + +/* * String to HEXString conversion */ int string2hex(const unsigned char *, int, char **, int *); diff --git a/ext/openssl/ossl_pkcs7.c b/ext/openssl/ossl_pkcs7.c index fe1ef7c..b0cc656 100644 --- a/ext/openssl/ossl_pkcs7.c +++ b/ext/openssl/ossl_pkcs7.c @@ -572,12 +572,11 @@ ossl_pkcs7_add_certificate(VALUE self, VALUE cert) return self; } -static STACK * -pkcs7_get_certs_or_crls(VALUE self, int want_certs) +static STACK_OF(X509) * +pkcs7_get_certs(VALUE self) { PKCS7 *pkcs7; STACK_OF(X509) *certs; STACK_OF(X509_CRL) *crls; int i; - GetPKCS7(self, pkcs7); @@ -585,17 +584,38 @@ pkcs7_get_certs_or_crls(VALUE self, int want_certs) switch(i){ case NID_pkcs7_signed: certs = pkcs7->d.sign->cert; crls = pkcs7->d.sign->crl; break; case NID_pkcs7_signedAndEnveloped: certs = pkcs7->d.signed_and_enveloped->cert; + break; + default: + certs = NULL; + } + + return certs; +} + +static STACK_OF(X509_CRL) * +pkcs7_get_crls(VALUE self) +{ + PKCS7 *pkcs7; + STACK_OF(X509_CRL) *crls; + int i; + + GetPKCS7(self, pkcs7); + i = OBJ_obj2nid(pkcs7->type); + switch(i){ + case NID_pkcs7_signed: + crls = pkcs7->d.sign->crl; + break; + case NID_pkcs7_signedAndEnveloped: crls = pkcs7->d.signed_and_enveloped->crl; break; default: certs = crls = NULL; + crls = NULL; } + return want_certs ? certs : crls; return crls; } static VALUE @@ -610,7 +630,7 @@ ossl_pkcs7_set_certificates(VALUE self, VALUE ary) STACK_OF(X509) *certs; X509 *cert; + certs = pkcs7_get_certs_or_crls(self, 1); certs = pkcs7_get_certs(self); while((cert = sk_X509_pop(certs))) X509_free(cert); rb_block_call(ary, rb_intern("each"), 0, 0, ossl_pkcs7_set_certs_i, self); @@ -620,7 +640,7 @@ ossl_pkcs7_set_certificates(VALUE self, VALUE ary) static VALUE ossl_pkcs7_get_certificates(VALUE self) { return ossl_x509_sk2ary(pkcs7_get_certs_or_crls(self, 1)); + return ossl_x509_sk2ary(pkcs7_get_certs(self)); } static VALUE @@ -650,7 +670,7 @@ ossl_pkcs7_set_crls(VALUE self, VALUE ary) STACK_OF(X509_CRL) *crls; X509_CRL *crl; + crls = pkcs7_get_certs_or_crls(self, 0); crls = pkcs7_get_crls(self); while((crl = sk_X509_CRL_pop(crls))) X509_CRL_free(crl); rb_block_call(ary, rb_intern("each"), 0, 0, ossl_pkcs7_set_crls_i, self); @@ -660,7 +680,7 @@ ossl_pkcs7_set_crls(VALUE self, VALUE ary) static VALUE ossl_pkcs7_get_crls(VALUE self) { return ossl_x509crl_sk2ary(pkcs7_get_certs_or_crls(self, 0)); + return ossl_x509crl_sk2ary(pkcs7_get_crls(self)); } static VALUE diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c index 432ca21..facf6ca 100644 --- a/ext/openssl/ossl_ssl.c +++ b/ext/openssl/ossl_ssl.c @@ -1291,10 +1291,10 @@ ossl_ssl_get_peer_cert_chain(VALUE self) } chain = SSL_get_peer_cert_chain(ssl); if(!chain) return Qnil; num = sk_num(chain); + num = sk_X509_num(chain); ary = rb_ary_new2(num); for (i = 0; i < num; i++){ -cert = (X509*)sk_value(chain, i); +cert = sk_X509_value(chain, i); rb_ary_push(ary, ossl_x509_new(cert)); } diff --git a/ext/openssl/ossl_x509attr.c b/ext/openssl/ossl_x509attr.c index 1f817cd..2a4c481 100644 --- a/ext/openssl/ossl_x509attr.c +++ b/ext/openssl/ossl_x509attr.c @@ -218,8 +218,9 @@ ossl_x509attr_get_value(VALUE self) ossl_str_adjust(str, p); } else{ -length = i2d_ASN1_SET_OF_ASN1_TYPE(attr->value.set, NULL, -i2d_ASN1_TYPE, V_ASN1_SET, V_ASN1_UNIVERSAL, 0); +length = i2d_ASN1_SET_OF_ASN1_TYPE(attr->value.set, +(unsigned char **) NULL, i2d_ASN1_TYPE, +V_ASN1_SET, V_ASN1_UNIVERSAL, 0); str = rb_str_new(0, length); p = (unsigned char *)RSTRING_PTR(str); i2d_ASN1_SET_OF_ASN1_TYPE(attr->value.set, &p, diff --git a/ext/openssl/ossl_x509crl.c b/ext/openssl/ossl_x509crl.c index 1be9640..818fdba 100644 --- a/ext/openssl/ossl_x509crl.c +++ b/ext/openssl/ossl_x509crl.c @@ -264,7 +264,7 @@ ossl_x509crl_get_revoked(VALUE self) VALUE ary, revoked; GetX509CRL(self, crl); num = sk_X509_CRL_num(X509_CRL_get_REVOKED(crl)); num = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl)); if (num < 0) { OSSL_Debug("num < 0???"); return rb_ary_new(); @@ -272,7 +272,7 @@ ossl_x509crl_get_revoked(VALUE self) ary = rb_ary_new2(num); for(i=0; i<num; i++) { /* NO DUP - don't free! */ -rev = (X509_REVOKED *)sk_X509_CRL_value(X509_CRL_get_REVOKED(crl), i); +rev = sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i); revoked = ossl_x509revoked_new(rev); rb_ary_push(ary, revoked); } -1.7.0.3 + 1.26.4. tcs 1.26.4.1. support_joke.patch --- a/vm_opts.h +++ b/vm_opts.h @@ -46,6 +46,6 @@ #define OPT_STACK_CACHING 0 /* misc */ -#define SUPPORT_JOKE +#define SUPPORT_JOKE 0 1 #endif /* RUBY_VM_OPTS_H */ 1.26.5. ruby 1.26.5.1. 1.8.7 1.26.5.1.1. osx-arch-fix.patch diff --git a/Makefile.in b/Makefile.in index 656ae90..f976cf1 100644 --- a/Makefile.in +++ b/Makefile.in @@ -45,7 +45,7 @@ XLDFLAGS = @XLDFLAGS@ $(EXTLDFLAGS) EXTLIBS = LIBS = @LIBS@ $(EXTLIBS) MISSING = @LIBOBJS@ @ALLOCA@ -LDSHARED = @LIBRUBY_LDSHARED@ +LDSHARED = @LIBRUBY_LDSHARED@ $(LDFLAGS) DLDFLAGS = @LIBRUBY_DLDFLAGS@ $(EXTLDFLAGS) @ARCH_FLAG@ SOLIBS = @SOLIBS@ MAINLIBS = @MAINLIBS@ 1.26.5.1.2. no_sslv2.diff Index: ossl_ssl.c =================================================================== --- a/ext/openssl/ossl_ssl.c(revision 32381) +++ b/ext/openssl/ossl_ssl.c(revision 32382) @@ -107,9 +107,12 @@ OSSL_SSL_METHOD_ENTRY(TLSv1), OSSL_SSL_METHOD_ENTRY(TLSv1_server), OSSL_SSL_METHOD_ENTRY(TLSv1_client), +#if defined(HAVE_SSLV2_METHOD) && defined(HAVE_SSLV2_SERVER_METHOD) && \ + defined(HAVE_SSLV2_CLIENT_METHOD) OSSL_SSL_METHOD_ENTRY(SSLv2), OSSL_SSL_METHOD_ENTRY(SSLv2_server), OSSL_SSL_METHOD_ENTRY(SSLv2_client), +#endif OSSL_SSL_METHOD_ENTRY(SSLv3), OSSL_SSL_METHOD_ENTRY(SSLv3_server), OSSL_SSL_METHOD_ENTRY(SSLv3_client), 1.26.5.1.3. ruby187gc.patch --- a/intern.h(revision 31212) +++ b/intern.h(working copy) @@ -270,6 +270,15 @@ VALUE rb_gc_enable _((void)); VALUE rb_gc_disable _((void)); VALUE rb_gc_start _((void)); +VALUE rb_gc_enable_stats _((void)); +VALUE rb_gc_disable_stats _((void)); +VALUE rb_gc_allocated_size _((void)); +unsigned long rb_os_live_objects _((void)); +#ifdef HAVE_LONG_LONG +unsigned long long rb_os_allocated_objects _((void)); +#else +unsigned long rb_os_allocated_objects _((void)); +#endif /* hash.c */ void st_foreach_safe _((struct st_table *, int (*)(ANYARGS), unsigned long)); void rb_hash_foreach _((VALUE, int (*)(ANYARGS), VALUE)); --- a/gc.c(revision 31212) +++ b/gc.c(working copy) @@ -22,8 +22,16 @@ #include <setjmp.h> #include <sys/types.h> +#ifdef _WIN32 +#include <string.h> +#else +#include <strings.h> +#endif + #ifdef HAVE_SYS_TIME_H #include <sys/time.h> +#elif defined(_WIN32) +#include <time.h> #endif #ifdef HAVE_SYS_RESOURCE_H @@ -76,6 +84,20 @@ static VALUE nomem_error; static void garbage_collect(); +static unsigned long live_objects = 0; +unsigned long rb_os_live_objects() +{ return live_objects; } + +#if defined(HAVE_LONG_LONG) +static unsigned long long allocated_objects = 0; +unsigned long long rb_os_allocated_objects() +{ return allocated_objects; } +#else +static unsigned long allocated_objects = 0; +unsigned long rb_os_allocated_objects() +{ return allocated_objects; } +#endif + int ruby_gc_stress = 0; NORETURN(void rb_exc_jump _((VALUE))); @@ -132,6 +154,10 @@ return bool; } +long gc_allocated_size = 0; +long gc_num_allocations = 0; +static int gc_statistics = 0; + void * ruby_xmalloc(size) long size; @@ -156,6 +182,11 @@ } malloc_increase += size; + + + + + if (gc_statistics) { gc_allocated_size += size; gc_num_allocations += 1; } return mem; } @@ -205,8 +236,16 @@ RUBY_CRITICAL(free(x)); } +#if HAVE_LONG_LONG +#define GC_TIME_TYPE LONG_LONG +#else +#define GC_TIME_TYPE long +#endif + extern int ruby_in_compile; static int dont_gc; +static GC_TIME_TYPE gc_time = 0; +static int gc_collections = 0; static int during_gc; static int need_call_final = 0; static st_table *finalizer_table = 0; @@ -255,6 +294,139 @@ return old; } +/* + * call-seq: + * GC.enable_stats => true or false + * + * Enables garbage collection statistics, returning <code>true</code> if garbage + * collection statistics was already enabled. + * + * GC.enable_stats #=> false or true + * GC.enable_stats #=> true + * + */ + +VALUE +rb_gc_enable_stats() +{ + int old = gc_statistics; + gc_statistics = Qtrue; + return old; +} + +/* + * call-seq: + * GC.disable_stats => true or false + * + * Disables garbage collection statistics, returning <code>true</code> if garbage + * collection statistics was already disabled. + * + * GC.disable_stats #=> false or true + * GC.disable_stats #=> true + * + */ + +VALUE +rb_gc_disable_stats() +{ + int old = gc_statistics; + gc_statistics = Qfalse; + gc_allocated_size = 0; + gc_num_allocations = 0; + return old; +} + +/* + * call-seq: + * GC.clear_stats => nil + * + * Clears garbage collection statistics, returning nil. This resets the number + * of collections (GC.collections) and the time used (GC.time) to 0. + * + * GC.clear_stats #=> nil + * + */ + +VALUE +rb_gc_clear_stats() +{ + gc_collections = 0; + gc_time = 0; + gc_allocated_size = 0; + gc_num_allocations = 0; + return Qnil; +} + +/* + * call-seq: + * GC.allocated_size => Integer + * + * Returns the size of memory (in bytes) allocated since GC statistics collection + * was enabled. + * + * GC.allocated_size #=> 35 + * + */ +VALUE +rb_gc_allocated_size() +{ + return INT2NUM(gc_allocated_size); +} + +/* + * call-seq: + * GC.num_allocations => Integer + * + * Returns the number of memory allocations since GC statistics collection + * was enabled. + * + * GC.num_allocations #=> 150 + * + */ +VALUE +rb_gc_num_allocations() +{ + return INT2NUM(gc_num_allocations); +} + +/* + * call-seq: + * GC.collections => Integer + * + * Returns the number of garbage collections performed while GC statistics collection + * was enabled. + * + * GC.collections #=> 35 + * + */ + +VALUE +rb_gc_collections() +{ + return INT2NUM(gc_collections); +} + +/* + * call-seq: + * GC.time => Integer + * + * Returns the time spent during garbage collection while GC statistics collection + * was enabled (in micro seconds). + * + * GC.time #=> 20000 + * + */ + +VALUE +rb_gc_time() +{ +#if HAVE_LONG_LONG + return LL2NUM(gc_time); +#else + return LONG2NUM(gc_time); +#endif +} + VALUE rb_mGC; static struct gc_list { @@ -346,7 +518,7 @@ static RVALUE *freelist = 0; static RVALUE *deferred_final_list = 0; -#define HEAPS_INCREMENT 10 +static int heaps_increment = 10; static struct heaps_slot { void *membase; RVALUE *slot; @@ -355,13 +527,164 @@ static int heaps_length = 0; static int heaps_used = 0; -#define HEAP_MIN_SLOTS 10000 -static int heap_slots = HEAP_MIN_SLOTS; +static int heap_min_slots = 10000; +static int heap_slots = 10000; -#define FREE_MIN 4096 +static int heap_free_min = 4096; +static int heap_slots_increment = 10000; +static double heap_slots_growth_factor = 1.8; +static + +static + +static + static long initial_malloc_limit = GC_MALLOC_LIMIT; int verbose_gc_stats = Qfalse; FILE* gc_data_file = NULL; RVALUE *himem, *lomem; +static void set_gc_parameters() +{ + char *gc_stats_ptr, *min_slots_ptr, *free_min_ptr, *heap_slots_incr_ptr, + *heap_incr_ptr, *malloc_limit_ptr, *gc_heap_file_ptr, *heap_slots_growth_factor_ptr; + + gc_data_file = stderr; + + gc_stats_ptr = getenv("RUBY_GC_STATS"); + if (gc_stats_ptr != NULL) { + int gc_stats_i = atoi(gc_stats_ptr); + if (gc_stats_i > 0) { + verbose_gc_stats = Qtrue; + } + } + + gc_heap_file_ptr = getenv("RUBY_GC_DATA_FILE"); + if (gc_heap_file_ptr != NULL) { + FILE* data_file = fopen(gc_heap_file_ptr, "w"); + if (data_file != NULL) { + gc_data_file = data_file; + } + else { + fprintf(stderr, + "can't open gc log file %s for writing, using default\n", gc_heap_file_ptr); + } + } + + min_slots_ptr = getenv("RUBY_HEAP_MIN_SLOTS"); + if (min_slots_ptr != NULL) { + int min_slots_i = atoi(min_slots_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_MIN_SLOTS=%s\n", min_slots_ptr); + } + if (min_slots_i > 0) { + heap_slots = min_slots_i; + heap_min_slots = min_slots_i; + } + } + + free_min_ptr = getenv("RUBY_HEAP_FREE_MIN"); + if (free_min_ptr != NULL) { + int free_min_i = atoi(free_min_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_FREE_MIN=%s\n", free_min_ptr); + } + if (free_min_i > 0) { + heap_free_min = free_min_i; + } + } + + heap_incr_ptr = getenv("RUBY_HEAP_INCREMENT"); + if (heap_incr_ptr != NULL) { + int heap_incr_i = atoi(heap_incr_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_INCREMENT=%s\n", heap_incr_ptr); + } + if (heap_incr_i > 0) { + heaps_increment = heap_incr_i; + } + } + + heap_slots_incr_ptr = getenv("RUBY_HEAP_SLOTS_INCREMENT"); + if (heap_slots_incr_ptr != NULL) { + int heap_slots_incr_i = atoi(heap_slots_incr_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_SLOTS_INCREMENT=%s\n", heap_slots_incr_ptr); + } + if (heap_slots_incr_i > 0) { + heap_slots_increment = heap_slots_incr_i; + } + } + + heap_slots_growth_factor_ptr = getenv("RUBY_HEAP_SLOTS_GROWTH_FACTOR"); + if (heap_slots_growth_factor_ptr != NULL) { + double heap_slots_growth_factor_d = atoi(heap_slots_growth_factor_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_SLOTS_GROWTH_FACTOR=%s\n", heap_slots_growth_factor_ptr); + } + if (heap_slots_growth_factor_d > 0) { + heap_slots_growth_factor = heap_slots_growth_factor_d; + } + } + + malloc_limit_ptr = getenv("RUBY_GC_MALLOC_LIMIT"); + if (malloc_limit_ptr != NULL) { + int malloc_limit_i = atol(malloc_limit_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_GC_MALLOC_LIMIT=%s\n", malloc_limit_ptr); + } + if (malloc_limit_i > 0) { + initial_malloc_limit = malloc_limit_i; + } + } +} + +/* + * call-seq: + * GC.dump => nil + * + * dumps information about the current GC data structures to the GC log file + * + * GC.dump #=> nil + * + */ + +VALUE +rb_gc_dump() +{ + int i; + + for (i = 0; i < heaps_used; i++) { + int heap_size = heaps[i].limit; + fprintf(gc_data_file, "HEAP[%2d]: size=%7d\n", i, heap_size); + } + + return Qnil; +} + +/* + * call-seq: + * GC.log String => String + * + * Logs string to the GC data file and returns it. + * + * GC.log "manual GC call" #=> "manual GC call" + * + */ + +VALUE +rb_gc_log(self, original_str) + VALUE self, original_str; +{ + if (original_str == Qnil) { + fprintf(gc_data_file, "\n"); + } + else { + VALUE str = StringValue(original_str); + char *p = RSTRING(str)->ptr; + fprintf(gc_data_file, "%s\n", p); + } + return original_str; +} + static void add_heap() { @@ -372,7 +695,7 @@ struct heaps_slot *p; int length; -heaps_length += HEAPS_INCREMENT; +heaps_length += heaps_increment; length = heaps_length*sizeof(struct heaps_slot); RUBY_CRITICAL( if (heaps_used > 0) { @@ -388,10 +711,10 @@ for (;;) { RUBY_CRITICAL(p = (RVALUE*)malloc(sizeof(RVALUE)*(heap_slots+1))); if (p == 0) { if (heap_slots == HEAP_MIN_SLOTS) { + if (heap_slots == heap_min_slots) { rb_memerror(); } heap_slots = HEAP_MIN_SLOTS; + heap_slots = heap_min_slots; continue; } heaps[heaps_used].membase = p; @@ -407,8 +730,9 @@ if (lomem == 0 || lomem > p) lomem = p; if (himem < pend) himem = pend; heaps_used++; heap_slots *= 1.8; if (heap_slots <= 0) heap_slots = HEAP_MIN_SLOTS; + heap_slots += heap_slots_increment; + heap_slots_increment *= heap_slots_growth_factor; + if (heap_slots <= 0) heap_slots = heap_min_slots; while (p < pend) { p->as.free.flags = 0; @@ -442,6 +766,8 @@ RANY(obj)->file = ruby_sourcefile; RANY(obj)->line = ruby_sourceline; #endif + live_objects++; + allocated_objects++; return obj; } @@ -1102,6 +1428,39 @@ } } +static char* obj_type(int tp) +{ + switch (tp) { +case T_NIL : return "NIL"; +case T_OBJECT : return "OBJECT"; +case T_CLASS : return "CLASS"; +case T_ICLASS : return "ICLASS"; +case T_MODULE : return "MODULE"; +case T_FLOAT : return "FLOAT"; +case T_STRING : return "STRING"; +case T_REGEXP : return "REGEXP"; +case T_ARRAY : return "ARRAY"; +case T_FIXNUM : return "FIXNUM"; +case T_HASH : return "HASH"; +case T_STRUCT : return "STRUCT"; +case T_BIGNUM : return "BIGNUM"; +case T_FILE : return "FILE"; + +case T_TRUE : return "TRUE"; +case T_FALSE : return "FALSE"; +case T_DATA : return "DATA"; +case T_MATCH : return "MATCH"; +case T_SYMBOL : return "SYMBOL"; + +case T_BLKTAG : return "BLKTAG"; +case T_UNDEF : return "UNDEF"; +case T_VARMAP : return "VARMAP"; +case T_SCOPE : return "SCOPE"; +case T_NODE : return "NODE"; +default: return "____"; + } +} + static void free_unused_heaps() { @@ -1133,14 +1492,24 @@ int i; unsigned long live = 0; unsigned long free_min = 0; + live_objects = 0; + + + + + + + + + + + unsigned long really_freed = 0; int free_counts[256]; int live_counts[256]; int do_gc_stats = gc_statistics & verbose_gc_stats; for (i = 0; i < heaps_used; i++) { free_min += heaps[i].limit; } free_min = free_min * 0.2; if (free_min < FREE_MIN) free_min = FREE_MIN; if (free_min < heap_free_min) free_min = heap_free_min; if (do_gc_stats) { for (i = 0 ; i< 256; i++) { free_counts[i] = live_counts[i] = 0; } } if (ruby_in_compile && ruby_parser_stack_on_heap()) { /* should not reclaim nodes during compilation if yacc's semantic stack is not allocated on machine stack */ @@ -1171,6 +1540,11 @@ p = heaps[i].slot; pend = p + heaps[i].limit; while (p < pend) { if (!(p->as.basic.flags & FL_MARK)) { + if (p->as.basic.flags) { + if (do_gc_stats) { + really_freed++; + } + } if (p->as.basic.flags && ((deferred = obj_free((VALUE)p)) || ((FL_TEST(p, FL_FINALIZE)) && need_call_final))) { @@ -1183,6 +1557,12 @@ final_list = p; } else { + if (do_gc_stats) { + int obt = p->as.basic.flags & T_MASK; + if (obt) { + free_counts[obt]++; + } + } add_freelist(p); } n++; @@ -1193,7 +1573,10 @@ } else { RBASIC(p)->flags &= ~FL_MARK; -live++; +live_objects++; +if (do_gc_stats) { + live_counts[RANY((VALUE)p)->as.basic.flags & T_MASK]++; +} } p++; } @@ -1211,8 +1594,8 @@ } } if (malloc_increase > malloc_limit) { -malloc_limit += (malloc_increase - malloc_limit) * (double)live / (live + freed); -if (malloc_limit < GC_MALLOC_LIMIT) malloc_limit = GC_MALLOC_LIMIT; + malloc_limit += (malloc_increase - malloc_limit) * (double)live_objects / (live_objects + freed); + if (malloc_limit < initial_malloc_limit) malloc_limit = initial_malloc_limit; } malloc_increase = 0; if (freed < free_min) { @@ -1220,6 +1603,20 @@ } during_gc = 0; + + + + + + + + + + + + + + if (do_gc_stats) { fprintf(gc_data_file, "objects processed: %.7d\n", live+freed); fprintf(gc_data_file, "live objects: %.7d\n", live); fprintf(gc_data_file, "freelist objects : %.7d\n", freed - really_freed); fprintf(gc_data_file, "freed objects: %.7d\n", really_freed); for(i=0; i<256; i++) { if (free_counts[i]>0) { fprintf(gc_data_file, "kept %.7d / freed %.7d objects of type %s\n", live_counts[i], free_counts[i], obj_type(i)); } } } /* clear finalization list */ if (final_list) { deferred_final_list = final_list; @@ -1431,6 +1828,7 @@ struct gc_list *list; struct FRAME * volatile frame; /* gcc 2.7.2.3 -O2 bug?? jmp_buf save_regs_gc_mark; + struct timeval gctv1, gctv2; SET_STACK_END; */ #ifdef HAVE_NATIVETHREAD @@ -1447,6 +1845,14 @@ if (during_gc) return; during_gc++; + + + + + + + + if (gc_statistics) { gc_collections++; gettimeofday(&gctv1, NULL); if (verbose_gc_stats) { fprintf(gc_data_file, "Garbage collection started\n"); } } init_mark_stack(); gc_mark((VALUE)ruby_current_node, 0); @@ -1522,6 +1928,16 @@ } while (!MARK_STACK_EMPTY); gc_sweep(); if (gc_statistics) { GC_TIME_TYPE musecs_used; gettimeofday(&gctv2, NULL); musecs_used = ((GC_TIME_TYPE)(gctv2.tv_sec - gctv1.tv_sec) * 1000000) + (gctv2.tv_usec - gctv1.tv_usec); gc_time += musecs_used; + + + + + + + + + + if (verbose_gc_stats) { fprintf(gc_data_file, "GC time: %d msec\n", musecs_used / 1000); } } } void @@ -1703,6 +2119,7 @@ if (!rb_gc_stack_start) { Init_stack(0); } + set_gc_parameters(); add_heap(); } @@ -2147,6 +2564,33 @@ return (VALUE)((long)obj|FIXNUM_FLAG); } +/* call-seq: + * ObjectSpace.live_objects => number + * + * Returns the count of objects currently allocated in the system. This goes + * down after the garbage collector runs. + */ +static +VALUE os_live_objects(VALUE self) +{ return ULONG2NUM(live_objects); } + +/* call-seq: + * ObjectSpace.allocated_objects => number + * + * Returns the count of objects allocated since the Ruby interpreter has + * started. This number can only increase. To know how many objects are + * currently allocated, use ObjectSpace::live_objects + */ +static +VALUE os_allocated_objects(VALUE self) +{ +#if defined(HAVE_LONG_LONG) + return ULL2NUM(allocated_objects); +#else + return ULONG2NUM(allocated_objects); +#endif +} + /* * The <code>GC</code> module provides an interface to Ruby's mark and * sweep garbage collection mechanism. Some of the underlying methods @@ -2166,6 +2610,16 @@ rb_define_singleton_method(rb_mGC, "stress=", gc_stress_set, 1); rb_define_method(rb_mGC, "garbage_collect", rb_gc_start, 0); + + + + + + + + + + rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, "enable_stats", rb_gc_enable_stats, 0); "disable_stats", rb_gc_disable_stats, 0); "clear_stats", rb_gc_clear_stats, 0); "allocated_size", rb_gc_allocated_size, 0); "num_allocations", rb_gc_num_allocations, 0); "collections", rb_gc_collections, 0); "time", rb_gc_time, 0); "dump", rb_gc_dump, 0); "log", rb_gc_log, 1); rb_mObSpace = rb_define_module("ObjectSpace"); rb_define_module_function(rb_mObSpace, "each_object", os_each_obj, -1); rb_define_module_function(rb_mObSpace, "garbage_collect", rb_gc_start, 0); @@ -2173,6 +2627,8 @@ rb_define_module_function(rb_mObSpace, "remove_finalizer", rm_final, 1); rb_define_module_function(rb_mObSpace, "finalizers", finals, 0); rb_define_module_function(rb_mObSpace, "call_finalizer", call_final, 1); + rb_define_module_function(rb_mObSpace, "live_objects", os_live_objects, 0); + rb_define_module_function(rb_mObSpace, "allocated_objects", os_allocated_objects, 0); rb_define_module_function(rb_mObSpace, "define_finalizer", define_final, -1); rb_define_module_function(rb_mObSpace, "undefine_finalizer", undefine_final, 1); 1.26.5.1.4. hs.patch diff --git a/eval.c b/eval.c index b705302..909cd3d 100644 --- a/eval.c +++ b/eval.c @@ -73,6 +73,7 @@ char *strrchr _((const char*,const char)); #endif #include <time.h> +#include <sys/mman.h> #ifdef __BEOS__ #include <net/socket.h> @@ -1022,7 +1023,7 @@ static struct tag *prot_tag; _tag.blkid = 0;\ prot_tag = &_tag -#define PROT_NONE Qfalse/* 0 */ +#define PROT_EMPTY Qfalse/* 0 */ #define PROT_THREAD Qtrue/* 2 */ #define PROT_FUNC INT2FIX(0)/* 1 */ #define PROT_LOOP INT2FIX(1)/* 3 */ @@ -1234,7 +1235,7 @@ error_print() if (NIL_P(ruby_errinfo)) return; + PUSH_TAG(PROT_NONE); PUSH_TAG(PROT_EMPTY); if (EXEC_TAG() == 0) { errat = get_backtrace(ruby_errinfo); } @@ -1395,7 +1396,7 @@ ruby_init() /* default visibility is private at toplevel */ SCOPE_SET(SCOPE_PRIVATE); + PUSH_TAG(PROT_NONE); PUSH_TAG(PROT_EMPTY); if ((state = EXEC_TAG()) == 0) { rb_call_inits(); ruby_class = rb_cObject; @@ -1529,7 +1530,7 @@ ruby_options(argc, argv) int state; Init_stack((void*)&state); PUSH_TAG(PROT_NONE); PUSH_TAG(PROT_EMPTY); if ((state = EXEC_TAG()) == 0) { ruby_process_options(argc, argv); } @@ -1546,7 +1547,7 @@ void rb_exec_end_proc _((void)); static void ruby_finalize_0() { PUSH_TAG(PROT_NONE); + PUSH_TAG(PROT_EMPTY); if (EXEC_TAG() == 0) { rb_trap_exit(); } @@ -1584,7 +1585,7 @@ ruby_cleanup(ex) Init_stack((void *)&state); ruby_finalize_0(); errs[0] = ruby_errinfo; PUSH_TAG(PROT_NONE); + PUSH_TAG(PROT_EMPTY); PUSH_ITER(ITER_NOT); if ((state = EXEC_TAG()) == 0) { rb_thread_cleanup(); @@ -1635,7 +1636,7 @@ ruby_exec_internal() { int state; + + PUSH_TAG(PROT_NONE); PUSH_TAG(PROT_EMPTY); PUSH_ITER(ITER_NOT); /* default visibility is private at toplevel */ SCOPE_SET(SCOPE_PRIVATE); @@ -1857,7 +1858,7 @@ rb_eval_cmd(cmd, arg, level) } if (TYPE(cmd) != T_STRING) { PUSH_ITER(ITER_NOT); -PUSH_TAG(PROT_NONE); +PUSH_TAG(PROT_EMPTY); ruby_safe_level = level; if ((state = EXEC_TAG()) == 0) { val = rb_funcall2(cmd, rb_intern("call"), RARRAY(arg)->len, RARRAY(arg)->ptr); @@ -1879,7 +1880,7 @@ rb_eval_cmd(cmd, arg, level) ruby_safe_level = level; + PUSH_TAG(PROT_NONE); PUSH_TAG(PROT_EMPTY); if ((state = EXEC_TAG()) == 0) { val = eval(ruby_top_self, cmd, Qnil, 0, 0); } @@ -2386,7 +2387,7 @@ is_defined(self, node, buf) val = self; if (node->nd_recv == (NODE *)1) goto check_bound; case NODE_CALL: -PUSH_TAG(PROT_NONE); +PUSH_TAG(PROT_EMPTY); if ((state = EXEC_TAG()) == 0) { val = rb_eval(self, node->nd_recv); } @@ -2488,7 +2489,7 @@ is_defined(self, node, buf) break; case NODE_COLON2: -PUSH_TAG(PROT_NONE); +PUSH_TAG(PROT_EMPTY); if ((state = EXEC_TAG()) == 0) { val = rb_eval(self, node->nd_head); } @@ -2537,7 +2538,7 @@ is_defined(self, node, buf) goto again; default: -PUSH_TAG(PROT_NONE); +PUSH_TAG(PROT_EMPTY); if ((state = EXEC_TAG()) == 0) { rb_eval(self, node); } @@ -2741,7 +2742,7 @@ call_trace_func(event, node, self, id, klass) klass = rb_iv_get(klass, "__attached__"); } } PUSH_TAG(PROT_NONE); + PUSH_TAG(PROT_EMPTY); raised = rb_thread_reset_raised(th); if ((state = EXEC_TAG()) == 0) { srcfile = rb_str_new2(ruby_sourcefile?ruby_sourcefile:"(ruby)"); @@ -3304,7 +3305,7 @@ rb_eval(self, n) volatile VALUE e_info = ruby_errinfo; volatile int rescuing = 0; + PUSH_TAG(PROT_NONE); PUSH_TAG(PROT_EMPTY); if ((state = EXEC_TAG()) == 0) { retry_entry: result = rb_eval(self, node->nd_head); @@ -3353,7 +3354,7 @@ rb_eval(self, n) break; case NODE_ENSURE: -PUSH_TAG(PROT_NONE); +PUSH_TAG(PROT_EMPTY); if ((state = EXEC_TAG()) == 0) { result = rb_eval(self, node->nd_head); } @@ -3571,7 +3572,7 @@ rb_eval(self, n) ruby_frame = &frame; PUSH_SCOPE(); PUSH_TAG(PROT_NONE); PUSH_TAG(PROT_EMPTY); if (node->nd_rval) { saved_cref = ruby_cref; ruby_cref = (NODE*)node->nd_rval; @@ -4197,7 +4198,7 @@ module_setup(module, n) } + PUSH_CREF(module); PUSH_TAG(PROT_NONE); PUSH_TAG(PROT_EMPTY); if ((state = EXEC_TAG()) == 0) { EXEC_EVENT_HOOK(RUBY_EVENT_CLASS, n, ruby_cbase, ruby_frame->last_func, ruby_frame->last_class); @@ -4604,7 +4605,7 @@ rb_longjmp(tag, mesg) VALUE e = ruby_errinfo; int status; + -PUSH_TAG(PROT_NONE); +PUSH_TAG(PROT_EMPTY); if ((status = EXEC_TAG()) == 0) { StringValue(e); warn_printf("Exception `%s' at %s:%d - %s\n", @@ -4978,7 +4979,7 @@ rb_yield_0(val, self, klass, flags, avalue) var = block->var; if (var) { -PUSH_TAG(PROT_NONE); +PUSH_TAG(PROT_EMPTY); if ((state = EXEC_TAG()) == 0) { NODE *bvar = NULL; block_var: @@ -5051,7 +5052,7 @@ rb_yield_0(val, self, klass, flags, avalue) ruby_current_node = node; PUSH_ITER(block->iter); PUSH_TAG(lambda ? PROT_NONE : PROT_YIELD); PUSH_TAG(lambda ? PROT_EMPTY : PROT_YIELD); if ((state = EXEC_TAG()) == 0) { redo: if (nd_type(node) == NODE_CFUNC || nd_type(node) == NODE_IFUNC) { @@ -5464,7 +5465,7 @@ rb_rescue2(b_proc, data1, r_proc, data2, va_alist) VALUE eclass; va_list args; + + PUSH_TAG(PROT_NONE); PUSH_TAG(PROT_EMPTY); switch (state = EXEC_TAG()) { case TAG_RETRY: if (!handle) break; @@ -5522,7 +5523,7 @@ rb_protect(proc, data, state) VALUE result = Qnil;/* OK */ int status; + PUSH_TAG(PROT_NONE); PUSH_TAG(PROT_EMPTY); cont_protect = (VALUE)rb_node_newnode(NODE_MEMO, cont_protect, 0, 0); if ((status = EXEC_TAG()) == 0) { result = (*proc)(data); @@ -5550,7 +5551,7 @@ rb_ensure(b_proc, data1, e_proc, data2) volatile VALUE result = Qnil; VALUE retval; + PUSH_TAG(PROT_NONE); PUSH_TAG(PROT_EMPTY); if ((state = EXEC_TAG()) == 0) { result = (*b_proc)(data1); } @@ -5577,7 +5578,7 @@ rb_with_disable_interrupt(proc, data) int thr_critical = rb_thread_critical; rb_thread_critical = Qtrue; -PUSH_TAG(PROT_NONE); +PUSH_TAG(PROT_EMPTY); if ((status = EXEC_TAG()) == 0) { result = (*proc)(data); } @@ -6264,7 +6265,7 @@ rb_funcall_rescue(recv, mid, n, va_alist) va_init_list(ar, n); + PUSH_TAG(PROT_NONE); PUSH_TAG(PROT_EMPTY); if ((status = EXEC_TAG()) == 0) { result = vafuncall(recv, mid, n, &ar); } @@ -6539,7 +6540,7 @@ eval(self, src, scope, file, line) if (TYPE(ruby_class) == T_ICLASS) { ruby_class = RBASIC(ruby_class)->klass; } PUSH_TAG(PROT_NONE); + PUSH_TAG(PROT_EMPTY); if ((state = EXEC_TAG()) == 0) { NODE *node; @@ -6698,7 +6699,7 @@ exec_under(func, under, cbase, args) mode = scope_vmode; SCOPE_SET(SCOPE_PUBLIC); PUSH_TAG(PROT_NONE); + PUSH_TAG(PROT_EMPTY); if ((state = EXEC_TAG()) == 0) { val = (*func)(args); } @@ -7009,7 +7010,7 @@ rb_load(fname, wrap) PUSH_SCOPE(); /* default visibility is private at loading toplevel */ SCOPE_SET(SCOPE_PRIVATE); PUSH_TAG(PROT_NONE); + PUSH_TAG(PROT_EMPTY); state = EXEC_TAG(); last_func = ruby_frame->last_func; last_node = ruby_current_node; @@ -7068,7 +7069,7 @@ rb_load_protect(fname, wrap, state) { int status; + PUSH_TAG(PROT_NONE); PUSH_TAG(PROT_EMPTY); if ((status = EXEC_TAG()) == 0) { rb_load(fname, wrap); } @@ -7389,7 +7390,7 @@ rb_require_safe(fname, safe) saved.node = ruby_current_node; saved.func = ruby_frame->last_func; saved.safe = ruby_safe_level; PUSH_TAG(PROT_NONE); + PUSH_TAG(PROT_EMPTY); if ((state = EXEC_TAG()) == 0) { VALUE feature, path; long handle; @@ -8097,7 +8098,7 @@ rb_exec_end_proc() tmp_end_procs = link = ephemeral_end_procs; ephemeral_end_procs = 0; while (link) { PUSH_TAG(PROT_NONE); + PUSH_TAG(PROT_EMPTY); if ((status = EXEC_TAG()) == 0) { ruby_safe_level = link->safe; (*link->func)(link->data); @@ -8115,7 +8116,7 @@ rb_exec_end_proc() tmp_end_procs = link = end_procs; end_procs = 0; while (link) { PUSH_TAG(PROT_NONE); + PUSH_TAG(PROT_EMPTY); if ((status = EXEC_TAG()) == 0) { ruby_safe_level = link->safe; (*link->func)(link->data); @@ -8852,7 +8853,7 @@ proc_invoke(proc, args, self, klass) ruby_block = &_block; PUSH_ITER(ITER_CUR); ruby_frame->iter = ITER_CUR; PUSH_TAG(pcall ? PROT_LAMBDA : PROT_NONE); + PUSH_TAG(pcall ? PROT_LAMBDA : PROT_EMPTY); state = EXEC_TAG(); if (state == 0) { proc_set_safe_level(proc); @@ -10179,6 +10180,7 @@ win32_set_exception_list(p) int rb_thread_pending = 0; VALUE rb_cThread; +static unsigned int rb_thread_stack_size; extern VALUE rb_last_status; @@ -10406,12 +10408,20 @@ thread_mark(th) rb_gc_mark(th->thread); if (th->join) rb_gc_mark(th->join->thread); + + + + + + + + + + + + + rb_gc_mark(th->klass); rb_gc_mark(th->wrapper); rb_gc_mark((VALUE)th->cref); if (curr_thread == th) { rb_gc_mark(ruby_class); rb_gc_mark(ruby_wrapper); rb_gc_mark((VALUE)ruby_cref); rb_gc_mark((VALUE)ruby_scope); rb_gc_mark((VALUE)ruby_dyna_vars); } else { rb_gc_mark(th->klass); rb_gc_mark(th->wrapper); rb_gc_mark((VALUE)th->cref); rb_gc_mark((VALUE)th->scope); rb_gc_mark((VALUE)th->dyna_vars); } - rb_gc_mark((VALUE)th->scope); rb_gc_mark((VALUE)th->dyna_vars); rb_gc_mark(th->errinfo); rb_gc_mark(th->last_status); rb_gc_mark(th->last_line); @@ -10421,11 +10431,11 @@ thread_mark(th) rb_gc_mark_maybe(th->sandbox); /* mark data in copied stack */ if (th == curr_thread) return; if (th == main_thread) return; if (th->status == THREAD_KILLED) return; if (th->stk_len == 0) return; /* stack not active, no need to mark. */ if (th->stk_ptr) { -rb_gc_mark_locations(th->stk_ptr, th->stk_ptr+th->stk_len); + if (th->stk_ptr && th != curr_thread) { + rb_gc_mark_locations(th->stk_pos, th->stk_base); #if defined(THINK_C) || defined(__human68k__) rb_gc_mark_locations(th->stk_ptr+2, th->stk_ptr+th->stk_len+2); #endif @@ -10435,24 +10445,30 @@ thread_mark(th) } #endif } frame = th->frame; + + if (curr_thread == th) + frame = ruby_frame; + else + frame = th->frame; + while (frame && frame != top_frame) { -frame = ADJ(frame); rb_gc_mark_frame(frame); if (frame->tmp) { struct FRAME *tmp = frame->tmp; while (tmp && tmp != top_frame) { + -tmp = ADJ(tmp); rb_gc_mark_frame(tmp); tmp = tmp->prev; } } frame = frame->prev; } block = th->block; + + if (curr_thread == th) + block = ruby_block; + else + block = th->block; + while (block) { -block = ADJ(block); rb_gc_mark_frame(&block->frame); block = block->prev; } @@ -10515,7 +10531,7 @@ static inline void stack_free(th) rb_thread_t th; { if (th->stk_ptr) free(th->stk_ptr); + if (th->stk_ptr) munmap(th->stk_ptr, th->stk_size); th->stk_ptr = 0; #ifdef __ia64 if (th->bstr_ptr) free(th->bstr_ptr); @@ -10576,35 +10592,8 @@ rb_thread_save_context(th) static VALUE tval; len = ruby_stack_length(&pos); th->stk_len = 0; th->stk_pos = pos; if (len > th->stk_max) { -VALUE *ptr = realloc(th->stk_ptr, sizeof(VALUE) * len); -if (!ptr) rb_memerror(); -th->stk_ptr = ptr; -th->stk_max = len; } th->stk_len = len; FLUSH_REGISTER_WINDOWS; MEMCPY(th->stk_ptr, th->stk_pos, VALUE, th->stk_len); -#ifdef __ia64 th->bstr_pos = rb_gc_register_stack_start; len = (VALUE*)rb_ia64_bsp() - th->bstr_pos; th->bstr_len = 0; if (len > th->bstr_max) { VALUE *ptr = realloc(th->bstr_ptr, sizeof(VALUE) * len); if (!ptr) rb_memerror(); th->bstr_ptr = ptr; th->bstr_max = len; } th->bstr_len = len; rb_ia64_flushrs(); MEMCPY(th->bstr_ptr, th->bstr_pos, VALUE, th->bstr_len); -#endif -#ifdef SAVE_WIN32_EXCEPTION_LIST th->win32_exception_list = win32_get_exception_list(); -#endif + th->stk_pos = pos; th->frame = ruby_frame; th->scope = ruby_scope; ruby_scope->flags |= SCOPE_DONT_RECYCLE; @@ -10714,11 +10703,6 @@ rb_thread_restore_context_0(rb_thread_t th, int exit) #endif tmp = th; ex = exit; FLUSH_REGISTER_WINDOWS; MEMCPY(tmp->stk_pos, tmp->stk_ptr, VALUE, tmp->stk_len); -#ifdef __ia64 MEMCPY(tmp->bstr_pos, tmp->bstr_ptr, VALUE, tmp->bstr_len); -#endif tval = rb_lastline_get(); rb_lastline_set(tmp->last_line); @@ -10809,8 +10793,8 @@ rb_thread_restore_context(th, exit) rb_thread_t th; int exit; { if (!th->stk_ptr) rb_bug("unsaved context"); stack_extend(th, exit); + if (!th->stk_ptr && th != main_thread) rb_bug("unsaved context"); + rb_thread_restore_context_0(th, exit); } static void @@ -10829,7 +10813,6 @@ rb_thread_die(th) { th->thgroup = 0; th->status = THREAD_KILLED; stack_free(th); } static void @@ -12096,6 +12079,7 @@ rb_thread_group(thread) \ th->stk_ptr = 0;\ th->stk_len = 0;\ + th->stk_size = 0;\ th->stk_max = 0;\ th->wait_for = 0;\ IA64_INIT(th->bstr_ptr = 0);\ @@ -12143,6 +12127,48 @@ rb_thread_alloc(klass) THREAD_ALLOC(th); th->thread = Data_Wrap_Struct(klass, thread_mark, thread_free, th); + /* if main_thread != NULL, then this is NOT the main thread, so + * we create a heap-stack + */ + if (main_thread) { + /* Allocate stack, don't forget to add 1 extra word because of the MATH below */ + unsigned int pagesize = getpagesize(); + unsigned int total_size = rb_thread_stack_size + pagesize + sizeof(int); + void *stack_area = NULL; + + stack_area = mmap(NULL, total_size, PROT_READ | PROT_WRITE | PROT_EXEC, +MAP_PRIVATE | MAP_ANON, -1, 0); + + if (stack_area == MAP_FAILED) { +fprintf(stderr, "Thread stack allocation failed!\n"); +rb_memerror(); + } + + th->stk_ptr = th->stk_pos = stack_area; + th->stk_size = total_size; + + if (mprotect(th->stk_ptr, pagesize, PROT_NONE) == -1) { +fprintf(stderr, "Failed to create thread guard region: %s\n", strerror(errno)); +rb_memerror(); + } + + th->guard = th->stk_ptr + (pagesize/sizeof(VALUE *)); + + /* point stk_base at the top of the stack */ + /* ASSUMPTIONS: + * 1.) The address returned by malloc is "suitably aligned" for anything on this system + * 2.) Adding a value that is "aligned" for this platform should not unalign the address + * returned from malloc. + * 3.) Don't push anything on to the stack, otherwise it'll get unaligned. + * 4.) x86_64 ABI says aligned AFTER arguments have been pushed. You *must* then do a call[lq] + * or push[lq] something else on to the stack if you inted to do a ret. + */ + th->stk_base = th->stk_ptr + ((total_size - sizeof(int))/sizeof(VALUE *)); + th->stk_len = rb_thread_stack_size; + } else { + th->stk_ptr = th->stk_pos = rb_gc_stack_start; + } + for (vars = th->dyna_vars; vars; vars = vars->next) { if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break; FL_SET(vars, DVAR_DONT_RECYCLE); @@ -12246,17 +12272,22 @@ rb_thread_stop_timer() int rb_thread_tick = THREAD_TICK; #endif +struct thread_start_args { + VALUE (*fn)(); + void *arg; + rb_thread_t th; +} new_th; + +static VALUE +rb_thread_start_2(); + static VALUE rb_thread_start_0(fn, arg, th) VALUE (*fn)(); void *arg; rb_thread_t th; { volatile rb_thread_t th_save = th; volatile VALUE thread = th->thread; struct BLOCK *volatile saved_block = 0; enum rb_thread_status status; int state; if (OBJ_FROZEN(curr_thread->thgroup)) { rb_raise(rb_eThreadError, @@ -12284,16 +12315,41 @@ rb_thread_start_0(fn, arg, th) return thread; } if (ruby_block) {/* should nail down higher blocks */ -struct BLOCK dummy; + new_th.fn = fn; + new_th.arg = arg; + new_th.th = th; + +#if defined(__i386__) + __asm__ __volatile__ ("movl %0, %%esp\n\t" + "calll *%1\n" + :: "r" (th->stk_base), + "r" (rb_thread_start_2)); +#elif defined(__x86_64__) + __asm__ __volatile__ ("movq %0, %%rsp\n\t" + "callq *%1\n" + :: "r" (th->stk_base), + "r" (rb_thread_start_2)); +#else + #error unsupported architecture! +#endif + /* NOTREACHED */ + return 0; +} -dummy.prev = ruby_block; -blk_copy_prev(&dummy); -saved_block = ruby_block = dummy.prev; } scope_dup(ruby_scope); +static VALUE +rb_thread_start_2() +{ + volatile rb_thread_t th = new_th.th; + volatile rb_thread_t th_save = th; + volatile VALUE thread = th->thread; + struct BLOCK *volatile saved_block = 0; + enum rb_thread_status status; + int state; + struct tag *tag; + struct RVarmap *vars; + struct FRAME dummy_frame; + if (!th->next) { if (!th->next) { /* merge in thread list */ th->prev = curr_thread; curr_thread->next->prev = th; @@ -12301,13 +12357,27 @@ rb_thread_start_0(fn, arg, th) curr_thread->next = th; th->priority = curr_thread->priority; th->thgroup = curr_thread->thgroup; + } + curr_thread = th; + + dummy_frame = *ruby_frame; + dummy_frame.prev = top_frame; + ruby_frame = &dummy_frame; + + if (ruby_block) {/* should nail down higher blocks */ +struct BLOCK dummy; + +dummy.prev = ruby_block; +blk_copy_prev(&dummy); +saved_block = ruby_block = dummy.prev; } + + scope_dup(ruby_scope); PUSH_TAG(PROT_THREAD); if ((state = EXEC_TAG()) == 0) { if (THREAD_SAVE_CONTEXT(th) == 0) { curr_thread = th; th->result = (*fn)(arg, th); + th->result = (*new_th.fn)(new_th.arg, th); } th = th_save; } @@ -12644,6 +12714,43 @@ rb_thread_cleanup() END_FOREACH_FROM(curr, th); } +/* + * call-seq: + * Thread.stack_size => fixnum + * + * Returns the thread stack size in bytes + */ +static VALUE +rb_thread_stacksize_get() +{ + return INT2FIX(rb_thread_stack_size); +} + +/* + * call-seq: + * Thread.stack_size= fixnum => Qnil + * + * Sets the global thread stacksize and returns Qnil. + */ +static VALUE +rb_thread_stacksize_set(obj, val) + VALUE obj; + VALUE val; +{ + + unsigned int size = FIX2UINT(val); + + /* 16byte alignment works for both x86 and x86_64 */ + if (size & (~0xf)) { + size += 0x10; + size = size & (~0xf); + } + + rb_thread_stack_size = size; + + return Qnil; +} + int rb_thread_critical; @@ -13473,7 +13580,7 @@ rb_exec_recursive(func, obj, arg) int state; hash = recursive_push(hash, objid); -PUSH_TAG(PROT_NONE); +PUSH_TAG(PROT_EMPTY); if ((state = EXEC_TAG()) == 0) { result = (*func) (obj, arg, Qfalse); } @@ -13500,6 +13607,8 @@ Init_Thread() { VALUE cThGroup; + + rb_thread_stack_size = (1024 * 1024); recursive_key = rb_intern("__recursive_key__"); rb_eThreadError = rb_define_class("ThreadError", rb_eStandardError); rb_cThread = rb_define_class("Thread", rb_cObject); @@ -13524,6 +13633,9 @@ Init_Thread() rb_define_singleton_method(rb_cThread, "abort_on_exception", rb_thread_s_abort_exc, 0); rb_define_singleton_method(rb_cThread, "abort_on_exception=", rb_thread_s_abort_exc_set, 1); + + + rb_define_singleton_method(rb_cThread, "stack_size", rb_thread_stacksize_get, 0); rb_define_singleton_method(rb_cThread, "stack_size=", rb_thread_stacksize_set, 1); rb_define_method(rb_cThread, "run", rb_thread_run, 0); rb_define_method(rb_cThread, "wakeup", rb_thread_wakeup, 0); rb_define_method(rb_cThread, "kill", rb_thread_kill, 0); diff --git a/gc.c b/gc.c index a564f0b..d6d654d 100644 --- a/gc.c +++ b/gc.c @@ -506,12 +506,12 @@ stack_end_address(VALUE **stack_end_p) # define STACK_END (stack_end) #endif #if STACK_GROW_DIRECTION < 0 -# define STACK_LENGTH (rb_gc_stack_start - STACK_END) +# define STACK_LENGTH(start) ((start) - STACK_END) #elif STACK_GROW_DIRECTION > 0 -# define STACK_LENGTH (STACK_END - rb_gc_stack_start + 1) +# define STACK_LENGTH(start) (STACK_END - (start) + 1) #else -# define STACK_LENGTH ((STACK_END < rb_gc_stack_start) ? rb_gc_stack_start - STACK_END\ : STACK_END - rb_gc_stack_start + 1) +# define STACK_LENGTH(start) ((STACK_END < (start)) ? (start) - STACK_END\ + : STACK_END - (start) + 1) #endif #if STACK_GROW_DIRECTION > 0 # define STACK_UPPER(x, a, b) a @@ -534,27 +534,36 @@ stack_grow_direction(addr) #define GC_WATER_MARK 512 -#define CHECK_STACK(ret) do {\ +#define CHECK_STACK(ret, start) do {\ SET_STACK_END;\ (ret) = (STACK_LENGTH > STACK_LEVEL_MAX + GC_WATER_MARK);\ + (ret) = (STACK_LENGTH(start) > STACK_LEVEL_MAX + GC_WATER_MARK);\ } while (0) size_t ruby_stack_length(p) VALUE **p; { SET_STACK_END; if (p) *p = STACK_UPPER(STACK_END, rb_gc_stack_start, STACK_END); return STACK_LENGTH; + SET_STACK_END; + VALUE *start; + if (rb_curr_thread == rb_main_thread) { + start = rb_gc_stack_start; + } else { + start = rb_curr_thread->stk_base; + } + if (p) *p = STACK_UPPER(STACK_END, start, STACK_END); + return STACK_LENGTH(start); } int ruby_stack_check() { int ret; CHECK_STACK(ret); return ret; + int ret; + if (rb_curr_thread == rb_main_thread) { + CHECK_STACK(ret, rb_gc_stack_start); + } else { + CHECK_STACK(ret, rb_curr_thread->stk_base); + } + return ret; } #define MARK_STACK_MAX 1024 @@ -1441,10 +1450,13 @@ garbage_collect() init_mark_stack(); + + + + + + gc_mark((VALUE)ruby_current_node, 0); /* mark frame stack */ for (frame = ruby_frame; frame; frame = frame->prev) { if (rb_curr_thread == rb_main_thread) frame = ruby_frame; else frame = rb_main_thread->frame; for (; frame; frame = frame->prev) { rb_gc_mark_frame(frame); if (frame->tmp) { struct FRAME *tmp = frame->tmp; @@ -1454,16 +1466,35 @@ garbage_collect() } } } gc_mark((VALUE)ruby_scope, 0); gc_mark((VALUE)ruby_dyna_vars, 0); + + if (rb_curr_thread == rb_main_thread) { + gc_mark((VALUE)ruby_current_node, 0); + gc_mark((VALUE)ruby_scope, 0); + gc_mark((VALUE)ruby_dyna_vars, 0); + } else { + gc_mark((VALUE)rb_main_thread->node, 0); + gc_mark((VALUE)rb_main_thread->scope, 0); + gc_mark((VALUE)rb_main_thread->dyna_vars, 0); + + /* scan the current thread's stack */ + rb_gc_mark_locations((VALUE*)STACK_END, rb_curr_thread->stk_base); + } + if (finalizer_table) { -mark_tbl(finalizer_table, 0); + mark_tbl(finalizer_table, 0); } FLUSH_REGISTER_WINDOWS; /* This assumes that all registers are saved into the jmp_buf (and stack) */ rb_setjmp(save_regs_gc_mark); mark_locations_array((VALUE*)save_regs_gc_mark, sizeof(save_regs_gc_mark) / sizeof(VALUE *)); + + + + + + + /* If this is not the main thread, we need to scan the C stack, so * set STACK_END to the end of the C stack. */ if (rb_curr_thread != rb_main_thread) STACK_END = rb_main_thread->stk_pos; #if STACK_GROW_DIRECTION < 0 rb_gc_mark_locations((VALUE*)STACK_END, rb_gc_stack_start); #elif STACK_GROW_DIRECTION > 0 @@ -1483,6 +1514,7 @@ garbage_collect() rb_gc_mark_locations((VALUE*)((char*)STACK_END + 2), (VALUE*)((char*)rb_gc_stack_start + 2)); #endif + rb_gc_mark_threads(); /* mark protected global variables */ diff --git a/lib/logger.rb b/lib/logger.rb index 15d95fc..5a6d467 100644 --- a/lib/logger.rb +++ b/lib/logger.rb @@ -170,7 +170,7 @@ require 'monitor' class Logger VERSION = "1.2.6" - id, name, rev = %w$Id$ + id, name, rev = %w$Id logger.rb 1234$ ProgName = "#{name.chomp(",v")}/#{rev}" class Error < RuntimeError; end diff --git a/node.h b/node.h index c209fa5..740e66a 100644 --- a/node.h +++ b/node.h @@ -411,8 +411,11 @@ struct rb_thread { size_t stk_len; size_t stk_max; + size_t stk_size; VALUE *stk_ptr; VALUE *stk_pos; + VALUE *stk_base; + VALUE *guard; #ifdef __ia64 size_t bstr_len; size_t bstr_max; diff --git a/signal.c b/signal.c index fb21fd3..acac6a7 100644 --- a/signal.c +++ b/signal.c @@ -14,6 +14,7 @@ #include #include +#include #include #include "ruby.h" "rubysig.h" "node.h" <signal.h> <stdio.h> @@ -428,15 +429,22 @@ typedef RETSIGTYPE (*sighandler_t)_((int)); static sighandler_t ruby_signal(signum, handler) int signum; sighandler_t handler; + void *handler; { struct sigaction sigact, old; rb_trap_accept_nativethreads[signum] = 0; + + + + + + + + + sigact.sa_handler = handler; if (signum == SIGSEGV || signum == SIGBUS) { sigact.sa_sigaction = handler; sigact.sa_flags = (SA_ONSTACK | SA_RESETHAND | SA_SIGINFO); } else { sigact.sa_handler = handler; sigact.sa_flags = 0; } sigemptyset(&sigact.sa_mask); sigact.sa_flags = 0; # ifdef SA_NOCLDWAIT if (signum == SIGCHLD && handler == SIG_IGN) sigact.sa_flags |= SA_NOCLDWAIT; @@ -599,7 +607,132 @@ sighandler(sig) } } +#include <stdio.h> +#ifdef HAVE_STDARG_PROTOTYPES +#include <stdarg.h> +#define va_init_list(a,b) va_start(a,b) +#else +#include <varargs.h> +#define va_init_list(a,b) va_start(a) +#endif + +void +#ifdef HAVE_STDARG_PROTOTYPES +sig_printf(const char *fmt, ...) +#else + sig_printf(fmt, va_alist) + const char *fmt; + va_dcl +#endif +{ + char buf[BUFSIZ]; + va_list args; + FILE *out = stderr; + + va_init_list(args, fmt); + vfprintf(out, fmt, args); + va_end(args); + fprintf(out, "\n"); +} + +static void +dump_machine_state(uc) + ucontext_t *uc; +{ + const char *dump64 = + " ----------------- Register state dump ----------------------\n" + "rax = 0x%.16x rbx = 0x%.16x rcx = 0x%.16x rdx = 0x%.16x\n" + "rdi = 0x%.16x rsi = 0x%.16x rbp = 0x%.16x rsp = 0x%.16x\n" + "r8 = 0x%.16x r9 = 0x%.16x r10 = 0x%.16x r11 = 0x%.16x\n" + "r12 = 0x%.16x r13 = 0x%.16x r14 = 0x%.16x r15 = 0x%.16x\n" + "rip = 0x%.16x rflags = 0x%.16x cs = 0x%.16x fs = 0x%.16x\n" + "gs = 0x%.16x"; + + const char *dump32 = + " ----------------- Register state dump -------------------\n" + "eax = 0x%.8x ebx = 0x%.8x ecx = 0x%.8x edx = 0x%.8x\n" + "edi = 0x%.8x esi = 0x%.8x ebp = 0x%.8x esp = 0x%.8x\n" + "ss = 0x%.8x eflags = 0x%.8x eip = 0x%.8x cs = 0x%.8x\n" + "ds = 0x%.8x es = 0x%.8x fs = 0x%.8x gs = 0x%.8x\n"; + +#if defined(__LP64__) && defined(__APPLE__) + sig_printf(dump64, uc->uc_mcontext->__ss.__rax, uc->uc_mcontext->__ss.__rbx, + uc->uc_mcontext->__ss.__rcx, uc->uc_mcontext->__ss.__rdx, uc->uc_mcontext->__ss.__rdi, + uc->uc_mcontext->__ss.__rsi, uc->uc_mcontext->__ss.__rbp, uc->uc_mcontext->__ss.__rsp, + uc->uc_mcontext->__ss.__r8, uc->uc_mcontext->__ss.__r9, uc->uc_mcontext->__ss.__r10, + uc->uc_mcontext->__ss.__r11, uc->uc_mcontext->__ss.__r12, uc->uc_mcontext->__ss.__r13, + uc->uc_mcontext->__ss.__r14, uc->uc_mcontext->__ss.__r15, uc->uc_mcontext->__ss.__rip, + uc->uc_mcontext->__ss.__rflags, uc->uc_mcontext->__ss.__cs, uc->uc_mcontext->__ss.__fs, + uc->uc_mcontext->__ss.__gs); +#elif !defined(__LP64__) && defined(__APPLE__) + sig_printf(dump32, uc->uc_mcontext->__ss.__eax, uc->uc_mcontext->__ss.__ebx, + uc->uc_mcontext->__ss.__ecx, uc->uc_mcontext->__ss.__edx, + uc->uc_mcontext->__ss.__edi, uc->uc_mcontext->__ss.__esi, + uc->uc_mcontext->__ss.__ebp, uc->uc_mcontext->__ss.__esp, + uc->uc_mcontext->__ss.__ss, uc->uc_mcontext->__ss.__eflags, + uc->uc_mcontext->__ss.__eip, uc->uc_mcontext->__ss.__cs, + uc->uc_mcontext->__ss.__ds, uc->uc_mcontext->__ss.__es, + uc->uc_mcontext->__ss.__fs, uc->uc_mcontext->__ss.__gs); +#elif defined(__i386__) + sig_printf(dump32, uc->uc_mcontext.gregs[REG_EAX], uc->uc_mcontext.gregs[REG_EBX], + uc->uc_mcontext.gregs[REG_ECX], uc->uc_mcontext.gregs[REG_EDX], + uc->uc_mcontext.gregs[REG_EDI], uc->uc_mcontext.gregs[REG_ESI], + uc->uc_mcontext.gregs[REG_EBP], uc->uc_mcontext.gregs[REG_ESP], + uc->uc_mcontext.gregs[REG_SS], uc->uc_mcontext.gregs[REG_EFL], + uc->uc_mcontext.gregs[REG_EIP], uc->uc_mcontext.gregs[REG_EIP], + uc->uc_mcontext.gregs[REG_DS], uc->uc_mcontext.gregs[REG_ES], + uc->uc_mcontext.gregs[REG_FS], uc->uc_mcontext.gregs[REG_FS]); +#elif defined(__x86_64__) + sig_printf(dump64, uc->uc_mcontext.gregs[REG_RAX], uc->uc_mcontext.gregs[REG_RBX], + uc->uc_mcontext.gregs[REG_RCX], uc->uc_mcontext.gregs[REG_RDX], + uc->uc_mcontext.gregs[REG_RDI], uc->uc_mcontext.gregs[REG_RSI], + uc->uc_mcontext.gregs[REG_RBP], uc->uc_mcontext.gregs[REG_RSP], + uc->uc_mcontext.gregs[REG_R8], uc->uc_mcontext.gregs[REG_R9], + uc->uc_mcontext.gregs[REG_R10], uc->uc_mcontext.gregs[REG_R11], + uc->uc_mcontext.gregs[REG_R12], uc->uc_mcontext.gregs[REG_R13], + uc->uc_mcontext.gregs[REG_R14], uc->uc_mcontext.gregs[REG_R15], + uc->uc_mcontext.gregs[REG_RIP], uc->uc_mcontext.gregs[REG_EFL], + uc->uc_mcontext.gregs[REG_CSGSFS]); +#else +#endif +} + +static int +check_guard(caddr_t fault_addr, rb_thread_t th) { + if(fault_addr <= (caddr_t)rb_curr_thread->guard && + fault_addr >= (caddr_t)rb_curr_thread->stk_ptr) { + return 1; + } + return 0; +} + #ifdef SIGBUS +#ifdef POSIX_SIGNAL +static void sigbus _((int, siginfo_t*, void*)); +static void +sigbus(sig, ip, context) + int sig; + siginfo_t *ip; + void *context; +{ +#if defined(HAVE_NATIVETHREAD) && defined(HAVE_NATIVETHREAD_KILL) + if (!is_ruby_native_thread() && !rb_trap_accept_nativethreads[sig]) { + sigsend_to_ruby_thread(sig); + return; + } +#endif + + dump_machine_state(context); + if (check_guard((caddr_t)ip->si_addr, rb_curr_thread)) { + /* we hit the guard page, print out a warning to help app developers */ + rb_bug("Thread stack overflow! Try increasing it!"); + } else { + rb_bug("Bus Error"); + } +} + +#else /* !defined(POSIX_SIGNAL) */ + static RETSIGTYPE sigbus _((int)); static RETSIGTYPE sigbus(sig) @@ -615,8 +748,38 @@ sigbus(sig) rb_bug("Bus Error"); } #endif +#endif + #ifdef SIGSEGV +#ifdef POSIX_SIGNAL +static void sigsegv _((int, siginfo_t*, void*)); +static void +sigsegv(sig, ip, context) + int sig; + siginfo_t *ip; + void *context; +{ +#if defined(HAVE_NATIVETHREAD) && defined(HAVE_NATIVETHREAD_KILL) + if (!is_ruby_native_thread() && !rb_trap_accept_nativethreads[sig]) { + sigsend_to_ruby_thread(sig); + return; + } +#endif + + extern int ruby_gc_stress; + ruby_gc_stress = 0; + dump_machine_state(context); + if (check_guard((caddr_t)ip->si_addr, rb_curr_thread)) { + /* we hit the guard page, print out a warning to help app developers */ + rb_bug("Thread stack overflow! Try increasing it!"); + } else { + rb_bug("Segmentation fault"); + } +} + +#else /* !defined(POSIX_SIGNAL) */ + static RETSIGTYPE sigsegv _((int)); static RETSIGTYPE sigsegv(sig) @@ -634,6 +797,7 @@ sigsegv(sig) rb_bug("Segmentation fault"); } #endif +#endif #ifdef SIGPIPE static RETSIGTYPE sigpipe _((int)); @@ -705,7 +869,8 @@ static VALUE trap(arg) struct trap_arg *arg; { sighandler_t func, oldfunc; + sighandler_t oldfunc; + void *func; VALUE command, oldcmd; int sig = -1; const char *s; @@ -952,6 +1117,20 @@ sig_list() } static void +create_sigstack() +{ + stack_t ss; + ss.ss_size = SIGSTKSZ; + ss.ss_sp = malloc(ss.ss_size); + ss.ss_flags = 0; + if (sigaltstack(&ss, NULL) < 0) { + free(ss.ss_sp); + fprintf(stderr, "Couldn't create signal stack! Error %d: %s\n", errno, strerror(errno)); + exit(1); + } +} + +static void install_sighandler(signum, handler) int signum; sighandler_t handler; @@ -960,7 +1139,7 @@ install_sighandler(signum, handler) old = ruby_signal(signum, handler); if (old != SIG_DFL) { -ruby_signal(signum, old); + ruby_signal(signum, old); } } @@ -1089,6 +1268,8 @@ Init_signal() rb_alias(rb_eSignal, rb_intern("signm"), rb_intern("message")); rb_define_method(rb_eInterrupt, "initialize", interrupt_init, -1); + + create_sigstack(); install_sighandler(SIGINT, sighandler); #ifdef SIGHUP install_sighandler(SIGHUP, sighandler); 1.26.5.1.5. railsbench.patch diff --git a/gc.c b/gc.c index 52b1c23..f774022 100644 --- a/gc.c +++ b/gc.c @@ -22,8 +22,16 @@ #include <setjmp.h> #include <sys/types.h> +#ifdef _WIN32 +#include <string.h> +#else +#include <strings.h> +#endif + #ifdef HAVE_SYS_TIME_H #include <sys/time.h> +#elif defined(_WIN32) +#include <time.h> #endif #ifdef HAVE_SYS_RESOURCE_H @@ -42,7 +50,6 @@ void rb_io_fptr_finalize _((struct rb_io_t*)); #ifdef __CYGWIN__ int _setjmp(), _longjmp(); #endif /* Make alloca work the best possible way. */ #ifdef __GNUC__ # ifndef atarist @@ -205,8 +212,17 @@ ruby_xfree(x) RUBY_CRITICAL(free(x)); } +#if HAVE_LONG_LONG +#define GC_TIME_TYPE LONG_LONG +#else +#define GC_TIME_TYPE long +#endif + extern int ruby_in_compile; static int dont_gc; +static int gc_statistics = 0; +static GC_TIME_TYPE gc_time = 0; +static int gc_collections = 0; static int during_gc; static int need_call_final = 0; static st_table *finalizer_table = 0; @@ -241,7 +257,7 @@ rb_gc_enable() * Disables garbage collection, returning <code>true</code> if garbage * collection was already disabled. * - * GC.disable #=> false + * GC.disable #=> false or true * GC.disable #=> true * */ @@ -255,6 +271,104 @@ rb_gc_disable() return old; } +/* + * call-seq: + * GC.enable_stats => true or false + * + * Enables garbage collection statistics, returning <code>true</code> if garbage + * collection statistics was already enabled. + * + * GC.enable_stats #=> false or true + * GC.enable_stats #=> true + * + */ + +VALUE +rb_gc_enable_stats() +{ + int old = gc_statistics; + gc_statistics = Qtrue; + return old; +} + +/* + * call-seq: + * GC.disable_stats => true or false + * + * Disables garbage collection statistics, returning <code>true</code> if garbage + * collection statistics was already disabled. + * + * GC.disable_stats #=> false or true + * GC.disable_stats #=> true + * + */ + +VALUE +rb_gc_disable_stats() +{ + int old = gc_statistics; + gc_statistics = Qfalse; + return old; +} + +/* + * call-seq: + * GC.clear_stats => nil + * + * Clears garbage collection statistics, returning nil. This resets the number + * of collections (GC.collections) and the time used (GC.time) to 0. + * + * GC.clear_stats #=> nil + * + */ + +VALUE +rb_gc_clear_stats() +{ + gc_collections = 0; + gc_time = 0; + return Qnil; +} + +/* + * call-seq: + * GC.collections => Integer + * + * Returns the number of garbage collections performed while GC statistics collection + * was enabled. + * + * GC.collections #=> 35 + * + */ + +VALUE +rb_gc_collections() +{ + return INT2NUM(gc_collections); +} + +/* + * call-seq: + * GC.time => Integer + * + * Returns the time spent during garbage collection while GC statistics collection + * was enabled (in micro seconds). + * + * GC.time #=> 20000 + * + */ + +VALUE +rb_gc_time() +{ +#if HAVE_LONG_LONG + return LL2NUM(gc_time); +#else + return LONG2NUM(gc_time); +#endif +} + + VALUE rb_mGC; static struct gc_list { @@ -346,7 +460,7 @@ typedef struct RVALUE { static RVALUE *freelist = 0; static RVALUE *deferred_final_list = 0; -#define HEAPS_INCREMENT 10 +static int heaps_increment = 10; static struct heaps_slot { void *membase; RVALUE *slot; @@ -355,13 +469,165 @@ static struct heaps_slot { static int heaps_length = 0; static int heaps_used = 0; -#define HEAP_MIN_SLOTS 10000 -static int heap_slots = HEAP_MIN_SLOTS; +static int heap_min_slots = 10000; +static int heap_slots = 10000; + +static int heap_free_min = 4096; +static int heap_slots_increment = 10000; +static double heap_slots_growth_factor = 1.8; + +static long initial_malloc_limit = GC_MALLOC_LIMIT; -#define FREE_MIN 4096 +static int verbose_gc_stats = Qfalse; + +static FILE* gc_data_file = NULL; static RVALUE *himem, *lomem; +static void set_gc_parameters() +{ + char *gc_stats_ptr, *min_slots_ptr, *free_min_ptr, *heap_slots_incr_ptr, + *heap_incr_ptr, *malloc_limit_ptr, *gc_heap_file_ptr, *heap_slots_growth_factor_ptr; + + gc_data_file = stderr; + + gc_stats_ptr = getenv("RUBY_GC_STATS"); + if (gc_stats_ptr != NULL) { +int gc_stats_i = atoi(gc_stats_ptr); +if (gc_stats_i > 0) { + verbose_gc_stats = Qtrue; +} + } + + gc_heap_file_ptr = getenv("RUBY_GC_DATA_FILE"); + if (gc_heap_file_ptr != NULL) { +FILE* data_file = fopen(gc_heap_file_ptr, "w"); +if (data_file != NULL) { + gc_data_file = data_file; +} +else { + fprintf(stderr, + "can't open gc log file %s for writing, using default\n", gc_heap_file_ptr); +} + } + + min_slots_ptr = getenv("RUBY_HEAP_MIN_SLOTS"); + if (min_slots_ptr != NULL) { +int min_slots_i = atoi(min_slots_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_MIN_SLOTS=%s\n", min_slots_ptr); + } +if (min_slots_i > 0) { + heap_slots = min_slots_i; + heap_min_slots = min_slots_i; +} + } + + free_min_ptr = getenv("RUBY_HEAP_FREE_MIN"); + if (free_min_ptr != NULL) { +int free_min_i = atoi(free_min_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_FREE_MIN=%s\n", free_min_ptr); +} +if (free_min_i > 0) { + heap_free_min = free_min_i; +} + } + + heap_incr_ptr = getenv("RUBY_HEAP_INCREMENT"); + if (heap_incr_ptr != NULL) { +int heap_incr_i = atoi(heap_incr_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_INCREMENT=%s\n", heap_incr_ptr); +} +if (heap_incr_i > 0) { + heaps_increment = heap_incr_i; +} + } + + heap_slots_incr_ptr = getenv("RUBY_HEAP_SLOTS_INCREMENT"); + if (heap_slots_incr_ptr != NULL) { +int heap_slots_incr_i = atoi(heap_slots_incr_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_SLOTS_INCREMENT=%s\n", heap_slots_incr_ptr); +} +if (heap_slots_incr_i > 0) { + heap_slots_increment = heap_slots_incr_i; +} + } + + heap_slots_growth_factor_ptr = getenv("RUBY_HEAP_SLOTS_GROWTH_FACTOR"); + if (heap_slots_growth_factor_ptr != NULL) { +double heap_slots_growth_factor_d = atoi(heap_slots_growth_factor_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_SLOTS_GROWTH_FACTOR=%s\n", heap_slots_growth_factor_ptr); +} +if (heap_slots_growth_factor_d > 0) { + heap_slots_growth_factor = heap_slots_growth_factor_d; +} + } + + malloc_limit_ptr = getenv("RUBY_GC_MALLOC_LIMIT"); + if (malloc_limit_ptr != NULL) { +int malloc_limit_i = atol(malloc_limit_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_GC_MALLOC_LIMIT=%s\n", malloc_limit_ptr); +} +if (malloc_limit_i > 0) { + initial_malloc_limit = malloc_limit_i; +} + } +} + +/* + * call-seq: + * GC.dump => nil + * + * dumps information about the current GC data structures to the GC log file + * + * GC.dump #=> nil + * + */ + +VALUE +rb_gc_dump() +{ + int i; + + for (i = 0; i < heaps_used; i++) { +int heap_size = heaps[i].limit; +fprintf(gc_data_file, "HEAP[%2d]: size=%7d\n", i, heap_size); + } + + return Qnil; +} + +/* + * call-seq: + * GC.log String => String + * + * Logs string to the GC data file and returns it. + * + * GC.log "manual GC call" #=> "manual GC call" + * + */ + +VALUE +rb_gc_log(self, original_str) + VALUE self, original_str; +{ + if (original_str == Qnil) { + fprintf(gc_data_file, "\n"); + } + else { + VALUE str = StringValue(original_str); + char *p = RSTRING(str)->ptr; + fprintf(gc_data_file, "%s\n", p); + } + return original_str; +} + + static void add_heap() { @@ -372,7 +638,7 @@ add_heap() struct heaps_slot *p; int length; -heaps_length += HEAPS_INCREMENT; +heaps_length += heaps_increment; length = heaps_length*sizeof(struct heaps_slot); RUBY_CRITICAL( if (heaps_used > 0) { @@ -388,10 +654,10 @@ add_heap() for (;;) { RUBY_CRITICAL(p = (RVALUE*)malloc(sizeof(RVALUE)*(heap_slots+1))); if (p == 0) { if (heap_slots == HEAP_MIN_SLOTS) { + if (heap_slots == heap_min_slots) { rb_memerror(); } heap_slots = HEAP_MIN_SLOTS; + heap_slots = heap_min_slots; continue; } heaps[heaps_used].membase = p; @@ -407,8 +673,9 @@ add_heap() if (lomem == 0 || lomem > p) lomem = p; if (himem < pend) himem = pend; heaps_used++; heap_slots *= 1.8; if (heap_slots <= 0) heap_slots = HEAP_MIN_SLOTS; + heap_slots += heap_slots_increment; + heap_slots_increment *= heap_slots_growth_factor; + if (heap_slots <= 0) heap_slots = heap_min_slots; while (p < pend) { p->as.free.flags = 0; @@ -1102,6 +1369,39 @@ finalize_list(p) } } +static char* obj_type(int tp) +{ + switch (tp) { +case T_NIL : return "NIL"; +case T_OBJECT : return "OBJECT"; +case T_CLASS : return "CLASS"; +case T_ICLASS : return "ICLASS"; +case T_MODULE : return "MODULE"; +case T_FLOAT : return "FLOAT"; +case T_STRING : return "STRING"; +case T_REGEXP : return "REGEXP"; +case T_ARRAY : return "ARRAY"; +case T_FIXNUM : return "FIXNUM"; +case T_HASH : return "HASH"; +case T_STRUCT : return "STRUCT"; +case T_BIGNUM : return "BIGNUM"; +case T_FILE : return "FILE"; + +case T_TRUE : return "TRUE"; +case T_FALSE : return "FALSE"; +case T_DATA : return "DATA"; +case T_MATCH : return "MATCH"; +case T_SYMBOL : return "SYMBOL"; + +case T_BLKTAG : return "BLKTAG"; +case T_UNDEF : return "UNDEF"; +case T_VARMAP : return "VARMAP"; +case T_SCOPE : return "SCOPE"; +case T_NODE : return "NODE"; +default: return "____"; + } +} + static void free_unused_heaps() { @@ -1134,12 +1434,21 @@ gc_sweep() unsigned long live = 0; unsigned long free_min = 0; + + + + + unsigned long really_freed = 0; int free_counts[256]; int live_counts[256]; int do_gc_stats = gc_statistics & verbose_gc_stats; for (i = 0; i < heaps_used; i++) { free_min += heaps[i].limit; } free_min = free_min * 0.2; if (free_min < FREE_MIN) free_min = FREE_MIN; if (free_min < heap_free_min) free_min = heap_free_min; + + + + if (do_gc_stats) { +for (i = 0 ; i< 256; i++) { free_counts[i] = live_counts[i] = 0; } + } if (ruby_in_compile && ruby_parser_stack_on_heap()) { /* should not reclaim nodes during compilation @@ -1174,6 +1483,9 @@ gc_sweep() if (p->as.basic.flags && ((deferred = obj_free((VALUE)p)) || ((FL_TEST(p, FL_FINALIZE)) && need_call_final))) { + if (do_gc_stats) { +really_freed++; + } if (!deferred) { p->as.free.flags = T_DEFERRED; RDATA(p)->dfree = 0; @@ -1183,6 +1495,12 @@ gc_sweep() final_list = p; } else { + if (do_gc_stats) { + int obt = p->as.basic.flags & T_MASK; + if (obt) { + free_counts[obt]++; + } + } add_freelist(p); } n++; @@ -1194,6 +1512,9 @@ gc_sweep() else { RBASIC(p)->flags &= ~FL_MARK; live++; +if (do_gc_stats) { + live_counts[RANY((VALUE)p)->as.basic.flags & T_MASK]++; + } } p++; } @@ -1212,7 +1533,7 @@ gc_sweep() } if (malloc_increase > malloc_limit) { malloc_limit += (malloc_increase - malloc_limit) * (double)live / (live + freed); -if (malloc_limit < GC_MALLOC_LIMIT) malloc_limit = GC_MALLOC_LIMIT; +if (malloc_limit < initial_malloc_limit) malloc_limit = initial_malloc_limit; } malloc_increase = 0; if (freed < free_min) { @@ -1220,6 +1541,20 @@ gc_sweep() } during_gc = 0; + if (do_gc_stats) { +fprintf(gc_data_file, "objects processed: %.7d\n", live+freed); +fprintf(gc_data_file, "live objects: %.7d\n", live); +fprintf(gc_data_file, "freelist objects : %.7d\n", freed - really_freed); +fprintf(gc_data_file, "freed objects: %.7d\n", really_freed); +for(i=0; i<256; i++) { + if (free_counts[i]>0) { +fprintf(gc_data_file, +"kept %.7d / freed %.7d objects of type %s\n", +live_counts[i], free_counts[i], obj_type(i)); + } +} + } + /* clear finalization list */ if (final_list) { deferred_final_list = final_list; @@ -1423,6 +1758,7 @@ garbage_collect() struct gc_list *list; struct FRAME * volatile frame; /* gcc 2.7.2.3 -O2 bug?? */ jmp_buf save_regs_gc_mark; + struct timeval gctv1, gctv2; SET_STACK_END; #ifdef HAVE_NATIVETHREAD @@ -1439,6 +1775,14 @@ garbage_collect() if (during_gc) return; during_gc++; + if (gc_statistics) { + gc_collections++; +gettimeofday(&gctv1, NULL); + if (verbose_gc_stats) { + fprintf(gc_data_file, "Garbage collection started\n"); +} + } + init_mark_stack(); gc_mark((VALUE)ruby_current_node, 0); @@ -1514,6 +1858,17 @@ garbage_collect() } while (!MARK_STACK_EMPTY); gc_sweep(); + + if (gc_statistics) { + GC_TIME_TYPE musecs_used; +gettimeofday(&gctv2, NULL); +musecs_used = ((GC_TIME_TYPE)(gctv2.tv_sec - gctv1.tv_sec) * 1000000) + (gctv2.tv_usec - gctv1.tv_usec); +gc_time += musecs_used; + +if (verbose_gc_stats) { + fprintf(gc_data_file, "GC time: %d msec\n", musecs_used / 1000); +} + } } void @@ -1695,6 +2050,7 @@ Init_heap() if (!rb_gc_stack_start) { Init_stack(0); } + set_gc_parameters(); add_heap(); } @@ -2163,6 +2519,14 @@ Init_GC() rb_define_singleton_method(rb_mGC, "stress=", gc_stress_set, 1); rb_define_method(rb_mGC, "garbage_collect", rb_gc_start, 0); + + + + + + + + rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, "enable_stats", rb_gc_enable_stats, 0); "disable_stats", rb_gc_disable_stats, 0); "clear_stats", rb_gc_clear_stats, 0); "collections", rb_gc_collections, 0); "time", rb_gc_time, 0); "dump", rb_gc_dump, 0); "log", rb_gc_log, 1); rb_mObSpace = rb_define_module("ObjectSpace"); rb_define_module_function(rb_mObSpace, "each_object", os_each_obj, -1); rb_define_module_function(rb_mObSpace, "garbage_collect", rb_gc_start, 0); 1.26.5.1.6. fix-irb-completion.diff diff --git a/lib/irb/completion.rb b/lib/irb/completion.rb index 000658e..609dca3 100644 --- a/lib/irb/completion.rb +++ b/lib/irb/completion.rb @@ -157,7 +157,7 @@ module IRB end next if name != "IRB::Context" and /^(IRB|SLex|RubyLex|RubyToken)/ =~ name candidates.concat m.instance_methods(false) + candidates.concat m.instance_methods(false).map { |m| m.to_s } } candidates.sort! candidates.uniq! 1.26.5.1.7. stdout-rouge-fix.patch diff --git a/lib/mkmf.rb b/lib/mkmf.rb index c9e738a..7a8004d 100644 --- a/lib/mkmf.rb +++ b/lib/mkmf.rb @@ -201,20 +201,26 @@ end module Logging @log = nil @logfile = 'mkmf.log' - @orgerr = $stderr.dup - @orgout = $stdout.dup @postpone = 0 @quiet = $extmk + + + + + + + + + + def self::open @log ||= File::open(@logfile, 'w') @log.sync = true orgerr = $stderr.dup orgout = $stdout.dup $stderr.reopen(@log) $stdout.reopen(@log) yield ensure $stderr.reopen(@orgerr) $stdout.reopen(@orgout) if orgerr $stderr.reopen(orgerr) orgerr.close end if orgout $stdout.reopen(orgout) orgout.close end end def self::message(*s) 1.26.5.1.8. zlib-gc-fix.diff diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index b87e691..5f701ab 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -610,6 +610,7 @@ zstream_append_input(z, src, len) } #define zstream_append_input2(z,v)\ RB_GC_GUARD(v),\ zstream_append_input((z), RSTRING(v)->ptr, RSTRING(v)->len) + static void 1.26.5.1.9. readline-fix.diff diff --git a/ext/readline/extconf.rb b/ext/readline/extconf.rb index b820c0b..f299cba 100644 --- a/ext/readline/extconf.rb +++ b/ext/readline/extconf.rb @@ -59,6 +59,9 @@ have_func("rl_cleanup_after_signal") have_func("rl_clear_signals") have_func("rl_vi_editing_mode") have_func("rl_emacs_editing_mode") +# workaround for native windows. +/mswin|bccwin|mingw/ !~ RUBY_PLATFORM && have_readline_var("rl_catch_sigwinch") +/mswin|bccwin|mingw/ !~ RUBY_PLATFORM && have_readline_var("rl_catch_signals") have_func("replace_history_entry") have_func("remove_history") create_makefile("readline") diff --git a/ext/readline/readline.c b/ext/readline/readline.c index c9acaad..637cb99 100644 --- a/ext/readline/readline.c +++ b/ext/readline/readline.c @@ -833,6 +833,12 @@ Init_readline() #ifdef HAVE_RL_EVENT_HOOK rl_event_hook = readline_event; #endif +#ifdef HAVE_RL_CATCH_SIGNALS + rl_catch_signals = 0; +#endif +#ifdef HAVE_RL_CATCH_SIGWINCH + rl_catch_sigwinch = 0; +#endif #ifdef HAVE_RL_CLEAR_SIGNALS rl_clear_signals(); #endif 1.26.5.1.10. p357 1.26.5.1.10.1. railsexpress 1.26.5.1.10.1.1. 07-fork-support-for-gc-logging.patch diff --git a/gc.c b/gc.c index 9ad716f..a3cbe91 100644 --- a/gc.c +++ b/gc.c @@ -223,6 +223,8 @@ static int dont_gc; static int gc_statistics = 0; static GC_TIME_TYPE gc_time = 0; static int gc_collections = 0; +static int verbose_gc_stats = Qfalse; +static FILE* gc_data_file = NULL; static int during_gc; static int need_call_final = 0; static st_table *finalizer_table = 0; @@ -368,9 +370,148 @@ rb_gc_time() #endif } VALUE rb_mGC; +/* + * call-seq: + * GC.enable_trace => true or false + * + * Enables garbage collection tracing, returning <code>true</code> if garbage + * collection tracing was already enabled. + * + * GC.enable_trace #=> false or true + * GC.enable_trace #=> true + * + */ + +VALUE +rb_gc_enable_trace() +{ + int old = verbose_gc_stats; + verbose_gc_stats = Qtrue; + return old; +} + +/* + * call-seq: + * GC.disable_trace => true or false + * + * Disables garbage collection tracing, returning <code>true</code> if garbage + * collection tracing was already disabled. + * + * GC.disable_trace #=> false or true + * GC.disable_trace #=> true + * + */ + +VALUE +rb_gc_disable_trace() +{ + int old = verbose_gc_stats; + verbose_gc_stats = Qfalse; + return old; +} + +char* GC_LOGFILE_IVAR = "@gc_logfile_name"; + +/* + * call-seq: + * GC.log_file(filename=nil, mode="w") => boolean + * + * Changes the GC data log file. Closes the currently open logfile. + * Returns true if the file was successfully opened for + * writing. Returns false if the file could not be opened for + * writing. Returns the name of the current logfile (or nil) if no + * parameter is given. Restores logging to stderr when given nil as + * an argument. + * + * GC.log_file #=> nil + * GC.log_file "/tmp/gc.log" #=> true + * GC.log_file #=> "/tmp/gc.log" + * GC.log_file nil #=> true + * + */ + +VALUE +rb_gc_log_file(int argc, VALUE *argv, VALUE self) +{ + VALUE filename = Qnil; + VALUE mode_str = Qnil; + FILE* f = NULL; + char* mode = "w"; + + VALUE current_logfile_name = rb_iv_get(rb_mGC, GC_LOGFILE_IVAR); + + if (argc==0) + return current_logfile_name; + + rb_scan_args(argc, argv, "02", &filename, &mode_str); + + if (filename == Qnil) { + /* close current logfile and reset logfile to stderr */ + if (gc_data_file != stderr) { + fclose(gc_data_file); + gc_data_file = stderr; + rb_iv_set(rb_mGC, GC_LOGFILE_IVAR, Qnil); + } + return Qtrue; + } + + /* we have a real logfile name */ + filename = StringValue(filename); + + if (rb_equal(current_logfile_name, filename) == Qtrue) { + /* do nothing if we get the file name we're already logging to */ + return Qtrue; + } + + /* get mode for file opening */ + if (mode_str != Qnil) + { + mode = RSTRING(StringValue(mode_str))->ptr; + } + + /* try to open file in given mode */ + if (f = fopen(RSTRING(filename)->ptr, mode)) { + if (gc_data_file != stderr) { + fclose(gc_data_file); + } + gc_data_file = f; + rb_iv_set(rb_mGC, GC_LOGFILE_IVAR, filename); + } else { + return Qfalse; + } + return Qtrue; +} + + +/* + * Called from process.c before a fork. Flushes the gc log file to + * avoid writing the buffered output twice (once in the parent, and + * once in the child). + */ +void +rb_gc_before_fork() +{ + /* flush gc log file */ + fflush(gc_data_file); +} + +/* + * Called from process.c after a fork in the child process. Turns off + * logging, disables GC stats and resets all gc counters and timing + * information. + */ +void +rb_gc_after_fork() +{ + rb_gc_disable_stats(); + rb_gc_clear_stats(); + rb_gc_disable_trace(); + gc_data_file = stderr; + rb_iv_set(rb_mGC, GC_LOGFILE_IVAR, Qnil); +} + static struct gc_list { VALUE *varptr; struct gc_list *next; @@ -477,10 +618,6 @@ static double heap_slots_growth_factor = 1.8; static long initial_malloc_limit = GC_MALLOC_LIMIT; -static int verbose_gc_stats = Qfalse; -static FILE* gc_data_file = NULL; static RVALUE *himem, *lomem; static void set_gc_parameters() @@ -496,6 +633,8 @@ static void set_gc_parameters() if (gc_stats_i > 0) { verbose_gc_stats = Qtrue; } + /* child processes should not inherit RUBY_GC_STATS */ + unsetenv("RUBY_GC_STATS"); } gc_heap_file_ptr = getenv("RUBY_GC_DATA_FILE"); @@ -508,6 +647,8 @@ static void set_gc_parameters() fprintf(stderr, "can't open gc log file %s for writing, using default\n", gc_heap_file_ptr); } + /* child processes should not inherit RUBY_GC_DATA_FILE to avoid clobbering */ + unsetenv("RUBY_GC_DATA_FILE"); } min_slots_ptr = getenv("RUBY_HEAP_MIN_SLOTS"); @@ -2619,6 +2760,9 @@ Init_GC() rb_define_singleton_method(rb_mGC, "dump_file_and_line_info", rb_gc_dump_file_and_line_info, -1); #endif rb_define_singleton_method(rb_mGC, "log", rb_gc_log, 1); + rb_define_singleton_method(rb_mGC, "log_file", rb_gc_log_file, -1); + rb_define_singleton_method(rb_mGC, "enable_trace", rb_gc_enable_trace, 0); + rb_define_singleton_method(rb_mGC, "disable_trace", rb_gc_disable_trace, 0); rb_mObSpace = rb_define_module("ObjectSpace"); rb_define_module_function(rb_mObSpace, "each_object", os_each_obj, -1); diff --git a/intern.h b/intern.h index 950ae9d..99696f1 100644 --- a/intern.h +++ b/intern.h @@ -270,6 +270,8 @@ void rb_gc_call_finalizer_at_exit _((void)); VALUE rb_gc_enable _((void)); VALUE rb_gc_disable _((void)); VALUE rb_gc_start _((void)); +void rb_gc_before_fork _((void)); +void rb_gc_after_fork _((void)); /* hash.c */ void st_foreach_safe _((struct st_table *, int (*)(ANYARGS), unsigned long)); void rb_hash_foreach _((VALUE, int (*)(ANYARGS), VALUE)); diff --git a/process.c b/process.c index 8f6285d..ea28cb8 100644 --- a/process.c +++ b/process.c @@ -1330,6 +1330,8 @@ rb_f_fork(obj) fflush(stderr); #endif + + rb_gc_before_fork(); before_exec(); pid = fork(); after_exec(); @@ -1339,6 +1341,7 @@ rb_f_fork(obj) #ifdef linux after_exec(); #endif + rb_gc_after_fork(); rb_thread_atfork(); if (rb_block_given_p()) { int status; @@ -1574,10 +1577,12 @@ rb_f_system(argc, argv) chfunc = signal(SIGCHLD, SIG_DFL); retry: + rb_gc_before_fork(); before_exec(); pid = fork(); if (pid == 0) { /* child process */ + rb_gc_after_fork(); rb_thread_atfork(); rb_protect(proc_exec_args, (VALUE)&earg, NULL); _exit(127); 1.26.5.1.10.1.2. 08-track-malloc-size.patch diff --git a/gc.c b/gc.c index a3cbe91..30a1219 100644 --- a/gc.c +++ b/gc.c @@ -79,6 +79,17 @@ void *alloca (); static unsigned long malloc_increase = 0; static unsigned long malloc_limit = GC_MALLOC_LIMIT; + +#ifdef HAVE_LONG_LONG +static unsigned LONG_LONG gc_allocated_size = 0; +static unsigned LONG_LONG gc_num_allocations = 0; +#else +static unsigned long gc_allocated_size = 0; +static unsigned long gc_num_allocations = 0; +#endif +static int gc_statistics = 0; + + static void run_final(); static VALUE nomem_error; static void garbage_collect(); @@ -163,6 +174,11 @@ ruby_xmalloc(size) } malloc_increase += size; + if (gc_statistics) { + gc_allocated_size += size; +gc_num_allocations += 1; + } + return mem; } @@ -220,7 +236,6 @@ ruby_xfree(x) extern int ruby_in_compile; static int dont_gc; -static int gc_statistics = 0; static GC_TIME_TYPE gc_time = 0; static int gc_collections = 0; static int verbose_gc_stats = Qfalse; @@ -329,11 +344,55 @@ rb_gc_clear_stats() { gc_collections = 0; gc_time = 0; + gc_allocated_size = 0; + gc_num_allocations = 0; return Qnil; } /* * call-seq: + * GC.allocated_size => Integer + * + * Returns the size of memory (in bytes) allocated since GC statistics collection + * was enabled. + * + * GC.allocated_size #=> 35 + * + */ +VALUE +rb_gc_allocated_size() +{ +#if HAVE_LONG_LONG + return ULL2NUM(gc_allocated_size); +#else + return ULONG2NUM(gc_allocated_size); +#endif +} + +/* + * call-seq: + * GC.num_allocations => Integer + * + * Returns the number of memory allocations since GC statistics collection + * was enabled. + * + * GC.num_allocations #=> 150 + * + */ +VALUE +rb_gc_num_allocations() +{ +#if HAVE_LONG_LONG + return ULL2NUM(gc_num_allocations); +#else + return ULONG2NUM(gc_num_allocations); +#endif +} + +/* + +/* + * call-seq: * GC.collections => Integer * * Returns the number of garbage collections performed while GC statistics collection @@ -2753,6 +2812,8 @@ Init_GC() rb_define_singleton_method(rb_mGC, "enable_stats", rb_gc_enable_stats, 0); rb_define_singleton_method(rb_mGC, "disable_stats", rb_gc_disable_stats, 0); rb_define_singleton_method(rb_mGC, "clear_stats", rb_gc_clear_stats, 0); + rb_define_singleton_method(rb_mGC, "allocated_size", rb_gc_allocated_size, 0); + rb_define_singleton_method(rb_mGC, "num_allocations", rb_gc_num_allocations, 0); rb_define_singleton_method(rb_mGC, "collections", rb_gc_collections, 0); rb_define_singleton_method(rb_mGC, "time", rb_gc_time, 0); rb_define_singleton_method(rb_mGC, "dump", rb_gc_dump, 0); diff --git a/intern.h b/intern.h index 99696f1..1117614 100644 --- a/intern.h +++ b/intern.h @@ -272,6 +272,8 @@ VALUE rb_gc_disable _((void)); VALUE rb_gc_start _((void)); void rb_gc_before_fork _((void)); void rb_gc_after_fork _((void)); +VALUE rb_gc_allocated_size _((void)); +VALUE rb_gc_num_allocations _((void)); /* hash.c */ void st_foreach_safe _((struct st_table *, int (*)(ANYARGS), unsigned long)); void rb_hash_foreach _((VALUE, int (*)(ANYARGS), VALUE)); 1.26.5.1.10.1.3. 13-add-trace-stats-enabled-methods.patch diff --git a/gc.c b/gc.c index 57740d2..2c34932 100644 --- a/gc.c +++ b/gc.c @@ -350,6 +350,22 @@ rb_gc_disable_stats() /* * call-seq: + * GC.stats_enabled? => true or false + * + * Check whether GC stats have been enabled. + * + * GC.stats_enabled? #=> false or true + * + */ + +VALUE +rb_gc_stats_enabled() +{ + return gc_statistics ? Qtrue : Qfalse; +} + +/* + * call-seq: * GC.clear_stats => nil * * Clears garbage collection statistics, returning nil. This resets the number @@ -491,6 +507,22 @@ rb_gc_disable_trace() return old; } +/* + * call-seq: + * GC.trace_enabled? => true or false + * + * Check whether GC tracing has been enabled. + * + * GC.trace_enabled? #=> false or true + * + */ + +VALUE +rb_gc_trace_enabled() +{ + return verbose_gc_stats ? Qtrue : Qfalse; +} + char* GC_LOGFILE_IVAR = "@gc_logfile_name"; /* @@ -2887,6 +2919,7 @@ Init_GC() rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, + rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, @@ -2902,6 +2935,7 @@ Init_GC() rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, + rb_define_singleton_method(rb_mGC, "enable_stats", rb_gc_enable_stats, 0); "disable_stats", rb_gc_disable_stats, 0); "stats_enabled?", rb_gc_stats_enabled, 0); "clear_stats", rb_gc_clear_stats, 0); "allocated_size", rb_gc_allocated_size, 0); "num_allocations", rb_gc_num_allocations, 0); "log_file", rb_gc_log_file, -1); "enable_trace", rb_gc_enable_trace, 0); "disable_trace", rb_gc_disable_trace, 0); "trace_enabled?", rb_gc_trace_enabled, 0); rb_mObSpace = rb_define_module("ObjectSpace"); rb_define_module_function(rb_mObSpace, "each_object", os_each_obj, -1); 1.26.5.1.10.1.4. 12-heap-slot-size.patch diff --git a/gc.c b/gc.c index 7db1ef6..57740d2 100644 --- a/gc.c +++ b/gc.c @@ -2891,6 +2891,7 @@ Init_GC() rb_define_singleton_method(rb_mGC, "allocated_size", rb_gc_allocated_size, 0); rb_define_singleton_method(rb_mGC, "num_allocations", rb_gc_num_allocations, 0); rb_define_singleton_method(rb_mGC, "heap_slots", rb_gc_heap_slots, 0); + rb_define_const(rb_mGC, "HEAP_SLOT_SIZE", INT2FIX(sizeof(RVALUE))); rb_define_singleton_method(rb_mGC, "collections", rb_gc_collections, 0); rb_define_singleton_method(rb_mGC, "time", rb_gc_time, 0); rb_define_singleton_method(rb_mGC, "dump", rb_gc_dump, 0); 1.26.5.1.10.1.5. 14-track-live-dataset-size.patch diff --git a/gc.c b/gc.c index 2c34932..0ce7e68 100644 --- a/gc.c +++ b/gc.c @@ -89,6 +89,7 @@ static unsigned long gc_num_allocations = 0; #endif static int gc_statistics = 0; +static unsigned long heap_slots_live_after_last_gc = 0; static void run_final(); static VALUE nomem_error; @@ -465,6 +466,23 @@ rb_gc_time() #endif } +/* + * call-seq: + * GC.heap_slots_live_after_last_gc => Integer + * + * Returns the number of heap slots which were live after the last garbage collection. + * + * GC.heap_slots_live_after_last_gc #=> 231223 + * + */ +VALUE +rb_gc_heap_slots_live_after_last_gc() +{ + return ULONG2NUM(heap_slots_live_after_last_gc); +} + + + VALUE rb_mGC; /* @@ -1903,6 +1921,7 @@ gc_sweep() } during_gc = 0; live_objects = live; + heap_slots_live_after_last_gc = live; if (do_gc_stats) { fprintf(gc_data_file, "objects processed: %.7d\n", live+freed); @@ -2924,6 +2943,7 @@ Init_GC() rb_define_singleton_method(rb_mGC, "allocated_size", rb_gc_allocated_size, 0); rb_define_singleton_method(rb_mGC, "num_allocations", rb_gc_num_allocations, 0); rb_define_singleton_method(rb_mGC, "heap_slots", rb_gc_heap_slots, 0); + rb_define_singleton_method(rb_mGC, "heap_slots_live_after_last_gc", rb_gc_heap_slots_live_after_last_gc, 0); rb_define_const(rb_mGC, "HEAP_SLOT_SIZE", INT2FIX(sizeof(RVALUE))); rb_define_singleton_method(rb_mGC, "collections", rb_gc_collections, 0); rb_define_singleton_method(rb_mGC, "time", rb_gc_time, 0); 1.26.5.1.10.1.6. 15-add-object-size-information-to-heap-dump.patch diff --git a/gc.c b/gc.c index 0ce7e68..53450bf 100644 --- a/gc.c +++ b/gc.c @@ -953,9 +953,21 @@ rb_gc_dump_file_and_line_info(int argc, VALUE *argv) if (!p->as.basic.klass) { fprintf(f, "__unknown__"); } else { fprintf(f, rb_obj_classname((VALUE)p)); + fprintf(f, "%s", rb_obj_classname((VALUE)p)); } } + /* print object size for some known object types */ + switch (TYPE(p)) { + case T_STRING: + fprintf(f, ":%lu", RSTRING(p)->len); + break; + case T_ARRAY: + fprintf(f, ":%lu", RARRAY(p)->len); + break; + case T_HASH: + fprintf(f, ":%d", RHASH(p)->tbl->num_entries); + break; + } } fprintf(f, "\n"); } @@ -1924,10 +1936,10 @@ gc_sweep() heap_slots_live_after_last_gc = live; if (do_gc_stats) { fprintf(gc_data_file, "objects processed: %.7d\n", live+freed); fprintf(gc_data_file, "live objects : %.7d\n", live); fprintf(gc_data_file, "freelist objects : %.7d\n", freed - really_freed); fprintf(gc_data_file, "freed objects : %.7d\n", really_freed); fprintf(gc_data_file, "objects processed: %.7lu\n", live+freed); fprintf(gc_data_file, "live objects : %.7lu\n", live); fprintf(gc_data_file, "freelist objects : %.7lu\n", freed - really_freed); fprintf(gc_data_file, "freed objects : %.7lu\n", really_freed); for(i=0; i<256; i++) { if (free_counts[i]>0 || live_counts[i]>0) { fprintf(gc_data_file, @@ -2258,7 +2270,7 @@ garbage_collect() gc_time += musecs_used; + + + + if (verbose_gc_stats) { fprintf(gc_data_file, "GC time: %d msec\n", musecs_used / 1000); fprintf(gc_data_file, "GC time: %ld msec\n", (long)(musecs_used / 1000)); fflush(gc_data_file); } + } 1.26.5.1.10.1.7. 11-fix-heap-size-growth-logic.patch diff --git a/gc.c b/gc.c index 21b3f6b..7db1ef6 100644 --- a/gc.c +++ b/gc.c @@ -694,6 +694,7 @@ static int heap_size = 0; static static +static static int heap_free_min = 4096; int heap_slots_increment = 10000; int initial_heap_slots_increment = 10000; double heap_slots_growth_factor = 1.8; static long initial_malloc_limit = GC_MALLOC_LIMIT; @@ -771,14 +772,13 @@ static void set_gc_parameters() if (verbose_gc_stats) { fprintf(gc_data_file, "RUBY_HEAP_SLOTS_INCREMENT=%s\n", heap_slots_incr_ptr); } if (heap_slots_incr_i > 0) { heap_slots_increment = heap_slots_incr_i; } + heap_slots_increment = heap_slots_incr_i; + initial_heap_slots_increment = heap_slots_increment; } heap_slots_growth_factor_ptr = getenv("RUBY_HEAP_SLOTS_GROWTH_FACTOR"); if (heap_slots_growth_factor_ptr != NULL) { double heap_slots_growth_factor_d = atoi(heap_slots_growth_factor_ptr); + double heap_slots_growth_factor_d = atof(heap_slots_growth_factor_ptr); if (verbose_gc_stats) { fprintf(gc_data_file, "RUBY_HEAP_SLOTS_GROWTH_FACTOR=%s\n", heap_slots_growth_factor_ptr); } @@ -988,8 +988,13 @@ add_heap() if (lomem == 0 || lomem > p) lomem = p; if (himem < pend) himem = pend; heaps_used++; heap_slots += heap_slots_increment; heap_slots_increment *= heap_slots_growth_factor; + if (heaps_used == 1) + heap_slots = initial_heap_slots_increment; + else { + heap_slots_increment *= heap_slots_growth_factor; + heap_slots += heap_slots_increment; + } + if (heap_slots <= 0) heap_slots = heap_min_slots; while (p < pend) { @@ -1879,6 +1884,7 @@ gc_sweep() live_counts[i], free_counts[i], obj_type(i)); } } + rb_gc_dump(); fflush(gc_data_file); } 1.26.5.1.10.1.8. 04-display-full-stack-trace.patch diff --git a/eval.c b/eval.c index 6ff2560..fb3307c 100644 --- a/eval.c +++ b/eval.c @@ -1325,8 +1325,8 @@ error_print() int truncate = eclass == rb_eSysStackError; #define -#define -#define +#define +#define TRACE_MAX (TRACE_HEAD+TRACE_TAIL+5) TRACE_HEAD 8 TRACE_TAIL 5 TRACE_HEAD 100 TRACE_TAIL 100 ep = RARRAY(errat); for (i=1; i<ep->len; i++) { 1.26.5.1.10.1.9. 06-heap-dump-support.patch diff --git a/configure.in b/configure.in index 62b34a8..4be088c 100644 --- a/configure.in +++ b/configure.in @@ -1595,6 +1595,14 @@ fi LDFLAGS="-L. $LDFLAGS" AC_SUBST(ARCHFILE) +dnl enable gc debugging +AC_ARG_ENABLE(gcdebug, + [ --enable-gcdebug build garbage collector with debugging enabled. ], + [enable_gcdebug=$enableval]) +if test "$enable_gcdebug" = 'yes'; then + AC_DEFINE(GC_DEBUG, 1) +fi + dnl build rdoc index if requested RDOCTARGET="" AC_ARG_ENABLE(install-doc, diff --git a/gc.c b/gc.c index ab71d22..9ad716f 100644 --- a/gc.c +++ b/gc.c @@ -411,7 +411,6 @@ rb_gc_unregister_address(addr) } } -#undef GC_DEBUG void rb_global_variable(var) @@ -602,6 +601,85 @@ rb_gc_dump() return Qnil; } + +static char* obj_type(int tp); + +#ifdef GC_DEBUG +/* + * call-seq: + * GC.dump_file_and_line_info(String, boolean) => nil + * + * dumps information on which currently allocated object was created by which file and on which line + * + * GC.dump_file_and_line_info(String, boolean) #=> nil + * + * The second parameter specifies whether class names should be included in the dump. + * Note that including class names will allocate additional string objects on the heap. + * + */ + +VALUE +rb_gc_dump_file_and_line_info(int argc, VALUE *argv) +{ + VALUE filename, str, include_classnames = Qnil; + char *fname = NULL; + char *klass = NULL; + FILE* f = NULL; + int i,n = 0; + + rb_scan_args(argc, argv, "11", &filename, &include_classnames); + + str = StringValue(filename); + fname = RSTRING(str)->ptr; + f = fopen(fname, "w"); + + for (i = 0; i < heaps_used; i++) { + RVALUE *p, *pend; + + p = heaps[i].slot; pend = p + heaps[i].limit; + for (;p < pend; p++) { + if (p->as.basic.flags) { + fprintf(f, "%s:%s:%d", obj_type(p->as.basic.flags & T_MASK), p->file, p->line); + // rb_obj_classname will create objects on the heap, we need a better solution + if (include_classnames == Qtrue) { + /* write the class */ + fprintf(f, ":"); + switch (TYPE(p)) { + case T_NONE: + fprintf(f, "__none__"); + break; + case T_BLKTAG: + fprintf(f, "__blktag__"); + break; + case T_UNDEF: + fprintf(f, "__undef__"); + break; + case T_VARMAP: + fprintf(f, "__varmap__"); + break; + case T_SCOPE: + fprintf(f, "__scope__"); + break; + case T_NODE: + fprintf(f, "__node__"); + break; + default: + if (!p->as.basic.klass) { + fprintf(f, "__unknown__"); + } else { + fprintf(f, rb_obj_classname((VALUE)p)); + } + } + } + fprintf(f, "\n"); + } + } + } + fclose(f); + return Qnil; +} +#endif + /* * call-seq: * GC.log String => String @@ -1066,6 +1144,11 @@ gc_mark(ptr, lev) if (obj->as.basic.flags & FL_MARK) return; /* already marked */ obj->as.basic.flags |= FL_MARK; +#ifdef GC_DEBUG + /* mark our new reference point for sourcefile objects */ + mark_source_filename(RANY(obj)->file); +#endif + if (lev > GC_LEVEL_MAX || (lev == 0 && ruby_stack_check())) { if (!mark_stack_overflow) { if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) { @@ -1104,6 +1187,11 @@ gc_mark_children(ptr, lev) if (obj->as.basic.flags & FL_MARK) return; /* already marked */ obj->as.basic.flags |= FL_MARK; +#ifdef GC_DEBUG + /* mark our new reference point for sourcefile objects */ + mark_source_filename(RANY(obj)->file); +#endif + marking: if (FL_TEST(obj, FL_EXIVAR)) { rb_mark_generic_ivar(ptr); @@ -1550,6 +1638,7 @@ gc_sweep() live_counts[i], free_counts[i], obj_type(i)); } } + fflush(gc_data_file); } /* clear finalization list */ @@ -2526,6 +2615,9 @@ Init_GC() rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, +#ifdef GC_DEBUG + rb_define_singleton_method(rb_mGC, +#endif rb_define_singleton_method(rb_mGC, "collections", rb_gc_collections, 0); "time", rb_gc_time, 0); "dump", rb_gc_dump, 0); "dump_file_and_line_info", rb_gc_dump_file_and_line_info, -1); "log", rb_gc_log, 1); rb_mObSpace = rb_define_module("ObjectSpace"); 1.26.5.1.10.1.10. 01-ignore-generated-files.patch diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..00c347a --- /dev/null +++ b/.gitignore @@ -0,0 +1,95 @@ +.ext +.installed.list +.rbconfig.time +Makefile +autom4te.cache/ +config.h +config.status +configure +ext/Win32API/Makefile +ext/bigdecimal/Makefile +ext/curses/Makefile +ext/dbm/Makefile +ext/digest/Makefile +ext/digest/bubblebabble/Makefile +ext/digest/md5/Makefile +ext/digest/rmd160/Makefile +ext/digest/sha1/Makefile +ext/digest/sha2/Makefile +ext/dl/Makefile +ext/dl/call.func +ext/dl/callback.func +ext/dl/cbtable.func +ext/dl/dlconfig.h +ext/dl/dlconfig.rb +ext/enumerator/Makefile +ext/etc/Makefile +ext/fcntl/Makefile +ext/gdbm/Makefile +ext/iconv/Makefile +ext/io/wait/Makefile +ext/nkf/Makefile +ext/openssl/Makefile +ext/openssl/extconf.h +ext/pty/Makefile +ext/racc/cparse/Makefile +ext/readline/Makefile +ext/sdbm/Makefile +ext/socket/Makefile +ext/stringio/Makefile +ext/strscan/Makefile +ext/syck/Makefile +ext/syslog/Makefile +ext/thread/Makefile +ext/tk/Makefile +ext/tk/tkutil/Makefile +ext/win32ole/Makefile +ext/win32ole/.document +ext/zlib/Makefile +largefile.h +miniruby +parse.c +rbconfig.rb +ruby +enc.mk +ext/bigdecimal/extconf.h +ext/continuation/ +ext/coverage/ +ext/curses/extconf.h +ext/dbm/extconf.h +ext/digest/bubblebabble/extconf.h +ext/digest/extconf.h +ext/digest/md5/extconf.h +ext/digest/rmd160/extconf.h +ext/digest/sha1/extconf.h +ext/digest/sha2/extconf.h +ext/dl/callback.h +ext/dl/extconf.h +ext/etc/extconf.h +ext/fcntl/extconf.h +ext/fiber/ +ext/iconv/extconf.h +ext/io/wait/extconf.h +ext/json/ +ext/nkf/extconf.h +ext/pty/extconf.h +ext/racc/cparse/extconf.h +ext/readline/extconf.h +ext/ripper/ +ext/sdbm/extconf.h +ext/socket/constants.h +ext/socket/extconf.h +ext/stringio/extconf.h +ext/strscan/extconf.h +ext/syck/extconf.h +ext/syslog/extconf.h +ext/tk/extconf.h +ext/tk/tkutil/extconf.h +ext/zlib/extconf.h +miniprelude.c +prelude.c +revision.h +*.dylib +*.log +*.dSYM +patches-ruby* 1.26.5.1.10.1.11. 03-railsbench-gc-patch.patch diff --git a/gc.c b/gc.c index fa45cd1..ab71d22 100644 --- a/gc.c +++ b/gc.c @@ -22,8 +22,16 @@ #include <setjmp.h> #include <sys/types.h> +#ifdef _WIN32 +#include <string.h> +#else +#include <strings.h> +#endif + #ifdef HAVE_SYS_TIME_H #include <sys/time.h> +#elif defined(_WIN32) +#include <time.h> #endif #ifdef HAVE_SYS_RESOURCE_H @@ -42,7 +50,6 @@ void rb_io_fptr_finalize _((struct rb_io_t*)); #ifdef __CYGWIN__ int _setjmp(), _longjmp(); #endif /* Make alloca work the best possible way. */ #ifdef __GNUC__ # ifndef atarist @@ -86,12 +93,12 @@ rb_memerror() rb_thread_t th = rb_curr_thread; if (!nomem_error || -(rb_thread_raised_p(th, RAISED_NOMEMORY) && rb_safe_level() < 4)) { -fprintf(stderr, "[FATAL] failed to allocate memory\n"); -exit(1); + (rb_thread_raised_p(th, RAISED_NOMEMORY) && rb_safe_level() < 4)) { + fprintf(stderr, "[FATAL] failed to allocate memory\n"); + exit(1); } if (rb_thread_raised_p(th, RAISED_NOMEMORY)) { -rb_exc_jump(nomem_error); + rb_exc_jump(nomem_error); } rb_thread_raised_set(th, RAISED_NOMEMORY); rb_exc_raise(nomem_error); @@ -139,7 +146,7 @@ ruby_xmalloc(size) void *mem; if (size < 0) { -rb_raise(rb_eNoMemError, "negative allocation size (or too big)"); + rb_raise(rb_eNoMemError, "negative allocation size (or too big)"); } if (size == 0) size = 1; @@ -148,11 +155,11 @@ ruby_xmalloc(size) } RUBY_CRITICAL(mem = malloc(size)); if (!mem) { -garbage_collect(); -RUBY_CRITICAL(mem = malloc(size)); -if (!mem) { rb_memerror(); -} + garbage_collect(); + RUBY_CRITICAL(mem = malloc(size)); + if (!mem) { + rb_memerror(); + } } malloc_increase += size; @@ -179,17 +186,17 @@ ruby_xrealloc(ptr, size) void *mem; if (size < 0) { -rb_raise(rb_eArgError, "negative re-allocation size"); + rb_raise(rb_eArgError, "negative re-allocation size"); } if (!ptr) return xmalloc(size); if (size == 0) size = 1; if (ruby_gc_stress) garbage_collect(); RUBY_CRITICAL(mem = realloc(ptr, size)); if (!mem) { -garbage_collect(); -RUBY_CRITICAL(mem = realloc(ptr, size)); -if (!mem) { rb_memerror(); + garbage_collect(); + RUBY_CRITICAL(mem = realloc(ptr, size)); + if (!mem) { + rb_memerror(); } } malloc_increase += size; @@ -202,11 +209,20 @@ ruby_xfree(x) void *x; { if (x) -RUBY_CRITICAL(free(x)); + RUBY_CRITICAL(free(x)); } +#if HAVE_LONG_LONG +#define GC_TIME_TYPE LONG_LONG +#else +#define GC_TIME_TYPE long +#endif + extern int ruby_in_compile; static int dont_gc; +static int gc_statistics = 0; +static GC_TIME_TYPE gc_time = 0; +static int gc_collections = 0; static int during_gc; static int need_call_final = 0; static st_table *finalizer_table = 0; @@ -241,7 +257,7 @@ rb_gc_enable() * Disables garbage collection, returning <code>true</code> if garbage * collection was already disabled. * - * GC.disable #=> false + * GC.disable #=> false or true * GC.disable #=> true * */ @@ -255,6 +271,104 @@ rb_gc_disable() return old; } +/* + * call-seq: + * GC.enable_stats => true or false + * + * Enables garbage collection statistics, returning <code>true</code> if garbage + * collection statistics was already enabled. + * + * GC.enable_stats #=> false or true + * GC.enable_stats #=> true + * + */ + +VALUE +rb_gc_enable_stats() +{ + int old = gc_statistics; + gc_statistics = Qtrue; + return old; +} + +/* + * call-seq: + * GC.disable_stats => true or false + * + * Disables garbage collection statistics, returning <code>true</code> if garbage + * collection statistics was already disabled. + * + * GC.disable_stats #=> false or true + * GC.disable_stats #=> true + * + */ + +VALUE +rb_gc_disable_stats() +{ + int old = gc_statistics; + gc_statistics = Qfalse; + return old; +} + +/* + * call-seq: + * GC.clear_stats => nil + * + * Clears garbage collection statistics, returning nil. This resets the number + * of collections (GC.collections) and the time used (GC.time) to 0. + * + * GC.clear_stats #=> nil + * + */ + +VALUE +rb_gc_clear_stats() +{ + gc_collections = 0; + gc_time = 0; + return Qnil; +} + +/* + * call-seq: + * GC.collections => Integer + * + * Returns the number of garbage collections performed while GC statistics collection + * was enabled. + * + * GC.collections #=> 35 + * + */ + +VALUE +rb_gc_collections() +{ + return INT2NUM(gc_collections); +} + +/* + * call-seq: + * GC.time => Integer + * + * Returns the time spent during garbage collection while GC statistics collection + * was enabled (in micro seconds). + * + * GC.time #=> 20000 + * + */ + +VALUE +rb_gc_time() +{ +#if HAVE_LONG_LONG + return LL2NUM(gc_time); +#else + return LONG2NUM(gc_time); +#endif +} + + VALUE rb_mGC; static struct gc_list { @@ -281,19 +395,19 @@ rb_gc_unregister_address(addr) struct gc_list *tmp = global_List; if (tmp->varptr == addr) { -global_List = tmp->next; -RUBY_CRITICAL(free(tmp)); -return; + global_List = tmp->next; + RUBY_CRITICAL(free(tmp)); + return; } while (tmp->next) { -if (tmp->next->varptr == addr) { struct gc_list *t = tmp->next; + if (tmp->next->varptr == addr) { + struct gc_list *t = tmp->next; -} -tmp + + + + + tmp->next = tmp->next->next; RUBY_CRITICAL(free(t)); break; = tmp->next; tmp->next = tmp->next->next; RUBY_CRITICAL(free(t)); break; } tmp = tmp->next; } } @@ -312,26 +426,26 @@ rb_global_variable(var) typedef struct RVALUE { union { -struct { unsigned long flags;/* always 0 for freed obj */ struct RVALUE *next; -} free; -struct RBasic basic; -struct RObject object; -struct RClass klass; -struct RFloat flonum; -struct RString string; -struct RArray array; -struct RRegexp regexp; -struct RHash hash; -struct RData data; -struct RStruct rstruct; -struct RBignum bignum; -struct RFile file; -struct RNode node; -struct RMatch match; -struct RVarmap varmap; -struct SCOPE scope; + struct { + unsigned long flags; /* always 0 for freed obj */ + struct RVALUE *next; + } free; + struct RBasic basic; + struct RObject object; + struct RClass klass; + struct RFloat flonum; + struct RString string; + struct RArray array; + struct RRegexp regexp; + struct RHash hash; + struct RData data; + struct RStruct rstruct; + struct RBignum bignum; + struct RFile file; + struct RNode node; + struct RMatch match; + struct RVarmap varmap; + struct SCOPE scope; } as; #ifdef GC_DEBUG char *file; @@ -346,7 +460,7 @@ typedef struct RVALUE { static RVALUE *freelist = 0; static RVALUE *deferred_final_list = 0; -#define HEAPS_INCREMENT 10 +static int heaps_increment = 10; static struct heaps_slot { void *membase; RVALUE *slot; @@ -355,45 +469,197 @@ static struct heaps_slot { static int heaps_length = 0; static int heaps_used = 0; -#define HEAP_MIN_SLOTS 10000 -static int heap_slots = HEAP_MIN_SLOTS; +static int heap_min_slots = 10000; +static int heap_slots = 10000; -#define FREE_MIN 4096 +static int heap_free_min = 4096; +static int heap_slots_increment = 10000; +static double heap_slots_growth_factor = 1.8; + +static long initial_malloc_limit = GC_MALLOC_LIMIT; + +static int verbose_gc_stats = Qfalse; + +static FILE* gc_data_file = NULL; static RVALUE *himem, *lomem; +static void set_gc_parameters() +{ + char *gc_stats_ptr, *min_slots_ptr, *free_min_ptr, *heap_slots_incr_ptr, + *heap_incr_ptr, *malloc_limit_ptr, *gc_heap_file_ptr, *heap_slots_growth_factor_ptr; + + gc_data_file = stderr; + + gc_stats_ptr = getenv("RUBY_GC_STATS"); + if (gc_stats_ptr != NULL) { + int gc_stats_i = atoi(gc_stats_ptr); + if (gc_stats_i > 0) { + verbose_gc_stats = Qtrue; + } + } + + gc_heap_file_ptr = getenv("RUBY_GC_DATA_FILE"); + if (gc_heap_file_ptr != NULL) { + FILE* data_file = fopen(gc_heap_file_ptr, "w"); + if (data_file != NULL) { + gc_data_file = data_file; + } + else { + fprintf(stderr, + "can't open gc log file %s for writing, using default\n", gc_heap_file_ptr); + } + } + + min_slots_ptr = getenv("RUBY_HEAP_MIN_SLOTS"); + if (min_slots_ptr != NULL) { + int min_slots_i = atoi(min_slots_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_MIN_SLOTS=%s\n", min_slots_ptr); + } + if (min_slots_i > 0) { + heap_slots = min_slots_i; + heap_min_slots = min_slots_i; + } + } + + free_min_ptr = getenv("RUBY_HEAP_FREE_MIN"); + if (free_min_ptr != NULL) { + int free_min_i = atoi(free_min_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_FREE_MIN=%s\n", free_min_ptr); + } + if (free_min_i > 0) { + heap_free_min = free_min_i; + } + } + + heap_incr_ptr = getenv("RUBY_HEAP_INCREMENT"); + if (heap_incr_ptr != NULL) { + int heap_incr_i = atoi(heap_incr_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_INCREMENT=%s\n", heap_incr_ptr); + } + if (heap_incr_i > 0) { + heaps_increment = heap_incr_i; + } + } + + heap_slots_incr_ptr = getenv("RUBY_HEAP_SLOTS_INCREMENT"); + if (heap_slots_incr_ptr != NULL) { + int heap_slots_incr_i = atoi(heap_slots_incr_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_SLOTS_INCREMENT=%s\n", heap_slots_incr_ptr); + } + if (heap_slots_incr_i > 0) { + heap_slots_increment = heap_slots_incr_i; + } + } + + heap_slots_growth_factor_ptr = getenv("RUBY_HEAP_SLOTS_GROWTH_FACTOR"); + if (heap_slots_growth_factor_ptr != NULL) { + double heap_slots_growth_factor_d = atoi(heap_slots_growth_factor_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_SLOTS_GROWTH_FACTOR=%s\n", heap_slots_growth_factor_ptr); + } + if (heap_slots_growth_factor_d > 0) { + heap_slots_growth_factor = heap_slots_growth_factor_d; + } + } + + malloc_limit_ptr = getenv("RUBY_GC_MALLOC_LIMIT"); + if (malloc_limit_ptr != NULL) { + int malloc_limit_i = atol(malloc_limit_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_GC_MALLOC_LIMIT=%s\n", malloc_limit_ptr); + } + if (malloc_limit_i > 0) { + initial_malloc_limit = malloc_limit_i; + } + } +} + +/* + * call-seq: + * GC.dump => nil + * + * dumps information about the current GC data structures to the GC log file + * + * GC.dump #=> nil + * + */ + +VALUE +rb_gc_dump() +{ + int i; + + for (i = 0; i < heaps_used; i++) { + int heap_size = heaps[i].limit; + fprintf(gc_data_file, "HEAP[%2d]: size=%7d\n", i, heap_size); + } + + return Qnil; +} + +/* + * call-seq: + * GC.log String => String + * + * Logs string to the GC data file and returns it. + * + * GC.log "manual GC call" #=> "manual GC call" + * + */ + +VALUE +rb_gc_log(self, original_str) + VALUE self, original_str; +{ + if (original_str == Qnil) { + fprintf(gc_data_file, "\n"); + } + else { + VALUE str = StringValue(original_str); + char *p = RSTRING(str)->ptr; + fprintf(gc_data_file, "%s\n", p); + } + return original_str; +} + + static void add_heap() { RVALUE *p, *pend; if (heaps_used == heaps_length) { -/* Realloc heaps */ -struct heaps_slot *p; -int length; -heaps_length += HEAPS_INCREMENT; -length = heaps_length*sizeof(struct heaps_slot); -RUBY_CRITICAL( if (heaps_used > 0) { -p = (struct heaps_slot *)realloc(heaps, length); -if (p) heaps = p; } else { -p = heaps = (struct heaps_slot *)malloc(length); }); -if (p == 0) rb_memerror(); + /* Realloc heaps */ + struct heaps_slot *p; + int length; + + heaps_length += heaps_increment; + length = heaps_length*sizeof(struct heaps_slot); + RUBY_CRITICAL( + if (heaps_used > 0) { + p = (struct heaps_slot *)realloc(heaps, length); + if (p) heaps = p; + } + else { + p = heaps = (struct heaps_slot *)malloc(length); + }); + if (p == 0) rb_memerror(); } for (;;) { -RUBY_CRITICAL(p = (RVALUE*)malloc(sizeof(RVALUE)*(heap_slots+1))); -if (p == 0) { if (heap_slots == HEAP_MIN_SLOTS) { -rb_memerror(); } heap_slots = HEAP_MIN_SLOTS; continue; -} + RUBY_CRITICAL(p = (RVALUE*)malloc(sizeof(RVALUE)*(heap_slots+1))); + if (p == 0) { + if (heap_slots == heap_min_slots) { + rb_memerror(); + } + heap_slots = heap_min_slots; + continue; + } heaps[heaps_used].membase = p; if ((VALUE)p % sizeof(RVALUE) == 0) heap_slots += 1; @@ -401,25 +667,26 @@ add_heap() p = (RVALUE*)((VALUE)p + sizeof(RVALUE) - ((VALUE)p % sizeof(RVALUE))); heaps[heaps_used].slot = p; heaps[heaps_used].limit = heap_slots; -break; + break; } pend = p + heap_slots; if (lomem == 0 || lomem > p) lomem = p; if (himem < pend) himem = pend; heaps_used++; heap_slots *= 1.8; if (heap_slots <= 0) heap_slots = HEAP_MIN_SLOTS; + heap_slots += heap_slots_increment; + heap_slots_increment *= heap_slots_growth_factor; + if (heap_slots <= 0) heap_slots = heap_min_slots; while (p < pend) { -p->as.free.flags = 0; -p->as.free.next = freelist; -freelist = p; -p++; + p->as.free.flags = 0; + p->as.free.next = freelist; + freelist = p; + p++; } } #define RANY(o) ((RVALUE*)(o)) -int +int rb_during_gc() { return during_gc; @@ -431,7 +698,7 @@ rb_newobj() VALUE obj; if (during_gc) -rb_bug("object allocation during garbage collection phase"); + rb_bug("object allocation during garbage collection phase"); if (ruby_gc_stress || !freelist) garbage_collect(); @@ -580,13 +847,13 @@ rb_source_filename(f) st_data_t name; if (!st_lookup(source_filenames, (st_data_t)f, &name)) { -long len = strlen(f) + 1; -char *ptr = ALLOC_N(char, len + 1); -name = (st_data_t)ptr; -*ptr++ = 0; -MEMCPY(ptr, f, char, len); -st_add_direct(source_filenames, (st_data_t)ptr, name); -return ptr; + long len = strlen(f) + 1; + char *ptr = ALLOC_N(char, len + 1); + name = (st_data_t)ptr; + *ptr++ = 0; + MEMCPY(ptr, f, char, len); + st_add_direct(source_filenames, (st_data_t)ptr, name); + return ptr; } return (char *)name + 1; } @@ -596,7 +863,7 @@ mark_source_filename(f) char *f; { if (f) { -f[-1] = 1; + f[-1] = 1; } } @@ -605,12 +872,12 @@ sweep_source_filename(key, value) char *key, *value; { if (*value) { -*value = 0; -return ST_CONTINUE; + *value = 0; + return ST_CONTINUE; } else { -free(value); -return ST_DELETE; + free(value); + return ST_DELETE; } } @@ -625,14 +892,14 @@ gc_mark_all() init_mark_stack(); for (i = 0; i < heaps_used; i++) { -p = heaps[i].slot; pend = p + heaps[i].limit; -while (p < pend) { if ((p->as.basic.flags & FL_MARK) && -(p->as.basic.flags != FL_MARK)) { -gc_mark_children((VALUE)p, 0); } p++; -} + p = heaps[i].slot; pend = p + heaps[i].limit; + while (p < pend) { + if ((p->as.basic.flags & FL_MARK) && + (p->as.basic.flags != FL_MARK)) { + gc_mark_children((VALUE)p, 0); + } + p++; + } } } @@ -647,8 +914,8 @@ gc_mark_rest() init_mark_stack(); while(p != tmp_arry){ -p--; -gc_mark_children(*p, 0); + + p--; gc_mark_children(*p, 0); } } @@ -665,9 +932,9 @@ is_pointer_to_heap(ptr) /* check if p looks like a pointer */ for (i=0; i < heaps_used; i++) { -heap_org = heaps[i].slot; -if (heap_org <= p && p < heap_org + heaps[i].limit) return Qtrue; + heap_org = heaps[i].slot; + if (heap_org <= p && p < heap_org + heaps[i].limit) + return Qtrue; } return Qfalse; } @@ -680,10 +947,10 @@ mark_locations_array(x, n) VALUE v; while (n--) { v = *x; -if (is_pointer_to_heap((void *)v)) { gc_mark(v, 0); -} -x++; + if (is_pointer_to_heap((void *)v)) { + gc_mark(v, 0); + } + x++; } } @@ -780,7 +1047,7 @@ rb_gc_mark_maybe(obj) VALUE obj; { if (is_pointer_to_heap((void *)obj)) { -gc_mark(obj, 0); + gc_mark(obj, 0); } } @@ -828,7 +1095,7 @@ gc_mark_children(ptr, lev) { register RVALUE *obj = RANY(ptr); + goto marking;/* skip */ goto marking; /* skip */ again: obj = RANY(ptr); @@ -839,148 +1106,148 @@ gc_mark_children(ptr, lev) marking: if (FL_TEST(obj, FL_EXIVAR)) { -rb_mark_generic_ivar(ptr); + rb_mark_generic_ivar(ptr); } switch (obj->as.basic.flags & T_MASK) { case T_NIL: case T_FIXNUM: -rb_bug("rb_gc_mark() called for broken object"); -break; + rb_bug("rb_gc_mark() called for broken object"); + break; case T_NODE: -mark_source_filename(obj->as.node.nd_file); -switch (nd_type(obj)) { - case NODE_IF:/* 1,2,3 */ - case NODE_FOR: - case NODE_ITER: - case NODE_CREF: - case NODE_WHEN: - case NODE_MASGN: - case NODE_RESCUE: - case NODE_RESBODY: - case NODE_CLASS: gc_mark((VALUE)obj->as.node.u2.node, lev); /* fall through */ - case NODE_BLOCK:/* 1,3 */ - case NODE_ARRAY: - case NODE_DSTR: - case NODE_DXSTR: - case NODE_DREGX: - case NODE_DREGX_ONCE: - case NODE_FBODY: - case NODE_ENSURE: - case NODE_CALL: - case NODE_DEFS: - case NODE_OP_ASGN1: gc_mark((VALUE)obj->as.node.u1.node, lev); /* fall through */ - case NODE_SUPER:/* 3 */ - case NODE_FCALL: - case NODE_DEFN: - case NODE_NEWLINE: ptr = (VALUE)obj->as.node.u3.node; goto again; - case NODE_WHILE:/* 1,2 */ - case NODE_UNTIL: - case NODE_AND: - case NODE_OR: - case NODE_CASE: - case NODE_SCLASS: - case NODE_DOT2: - case NODE_DOT3: - case NODE_FLIP2: - case NODE_FLIP3: - case NODE_MATCH2: - case NODE_MATCH3: - case NODE_OP_ASGN_OR: - case NODE_OP_ASGN_AND: - case NODE_MODULE: - case NODE_ALIAS: - case NODE_VALIAS: - case NODE_ARGS: gc_mark((VALUE)obj->as.node.u1.node, lev); /* fall through */ - case NODE_METHOD:/* 2 */ - case NODE_NOT: - case NODE_GASGN: - case NODE_LASGN: - case NODE_DASGN: - case NODE_DASGN_CURR: - case NODE_IASGN: - case NODE_CVDECL: - case NODE_CVASGN: - case NODE_COLON3: - case NODE_OPT_N: - case NODE_EVSTR: - case NODE_UNDEF: ptr = (VALUE)obj->as.node.u2.node; goto again; - case NODE_HASH:/* 1 */ - case NODE_LIT: - case NODE_STR: - case NODE_XSTR: - case NODE_DEFINED: - case NODE_MATCH: - case NODE_RETURN: - case NODE_BREAK: - case NODE_NEXT: - case NODE_YIELD: - case NODE_COLON2: - case NODE_SPLAT: - case NODE_TO_ARY: - case NODE_SVALUE: ptr = (VALUE)obj->as.node.u1.node; goto again; - case NODE_SCOPE:/* 2,3 */ - case NODE_BLOCK_PASS: - case NODE_CDECL: gc_mark((VALUE)obj->as.node.u3.node, lev); ptr = (VALUE)obj->as.node.u2.node; goto again; - case NODE_ZARRAY:/* - */ - case NODE_ZSUPER: - case NODE_CFUNC: - case NODE_VCALL: - case NODE_GVAR: - case NODE_LVAR: - case NODE_DVAR: - case NODE_IVAR: - case NODE_CVAR: - case NODE_NTH_REF: - case NODE_BACK_REF: - case NODE_REDO: - case NODE_RETRY: - case NODE_SELF: - case NODE_NIL: - case NODE_TRUE: - case NODE_FALSE: - case NODE_ATTRSET: - case NODE_BLOCK_ARG: - case NODE_POSTEXE: break; - case NODE_ALLOCA: mark_locations_array((VALUE*)obj->as.node.u1.value, - obj->as.node.u3.cnt); ptr = (VALUE)obj->as.node.u2.node; goto again; - default:/* unlisted NODE */ if (is_pointer_to_heap(obj->as.node.u1.node)) { -gc_mark((VALUE)obj->as.node.u1.node, lev); } if (is_pointer_to_heap(obj->as.node.u2.node)) { -gc_mark((VALUE)obj->as.node.u2.node, lev); } if (is_pointer_to_heap(obj->as.node.u3.node)) { -gc_mark((VALUE)obj->as.node.u3.node, lev); } -} -return;/* no need to mark class. */ + mark_source_filename(obj->as.node.nd_file); + switch (nd_type(obj)) { + case NODE_IF: /* 1,2,3 */ + case NODE_FOR: + case NODE_ITER: + case NODE_CREF: + case NODE_WHEN: + case NODE_MASGN: + case NODE_RESCUE: + case NODE_RESBODY: + case NODE_CLASS: + gc_mark((VALUE)obj->as.node.u2.node, lev); + /* fall through */ + case NODE_BLOCK: /* 1,3 */ + case NODE_ARRAY: + case NODE_DSTR: + case NODE_DXSTR: + case NODE_DREGX: + case NODE_DREGX_ONCE: + case NODE_FBODY: + case NODE_ENSURE: + case NODE_CALL: + case NODE_DEFS: + case NODE_OP_ASGN1: + gc_mark((VALUE)obj->as.node.u1.node, lev); + /* fall through */ + case NODE_SUPER: /* 3 */ + case NODE_FCALL: + case NODE_DEFN: + case NODE_NEWLINE: + ptr = (VALUE)obj->as.node.u3.node; + goto again; + + case NODE_WHILE: /* 1,2 */ + case NODE_UNTIL: + case NODE_AND: + case NODE_OR: + case NODE_CASE: + case NODE_SCLASS: + case NODE_DOT2: + case NODE_DOT3: + case NODE_FLIP2: + case NODE_FLIP3: + case NODE_MATCH2: + case NODE_MATCH3: + case NODE_OP_ASGN_OR: + case NODE_OP_ASGN_AND: + case NODE_MODULE: + case NODE_ALIAS: + case NODE_VALIAS: + case NODE_ARGS: + gc_mark((VALUE)obj->as.node.u1.node, lev); + /* fall through */ + case NODE_METHOD: /* 2 */ + case NODE_NOT: + case NODE_GASGN: + case NODE_LASGN: + case NODE_DASGN: + case NODE_DASGN_CURR: + case NODE_IASGN: + case NODE_CVDECL: + case NODE_CVASGN: + case NODE_COLON3: + case NODE_OPT_N: + case NODE_EVSTR: + case NODE_UNDEF: + ptr = (VALUE)obj->as.node.u2.node; + goto again; + + case NODE_HASH: /* 1 */ + case NODE_LIT: + case NODE_STR: + case NODE_XSTR: + case NODE_DEFINED: + case NODE_MATCH: + case NODE_RETURN: + case NODE_BREAK: + case NODE_NEXT: + case NODE_YIELD: + case NODE_COLON2: + case NODE_SPLAT: + case NODE_TO_ARY: + case NODE_SVALUE: + ptr = (VALUE)obj->as.node.u1.node; + goto again; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + case NODE_SCOPE: /* 2,3 */ case NODE_BLOCK_PASS: case NODE_CDECL: gc_mark((VALUE)obj->as.node.u3.node, lev); ptr = (VALUE)obj->as.node.u2.node; goto again; case NODE_ZARRAY: /* - */ case NODE_ZSUPER: case NODE_CFUNC: case NODE_VCALL: case NODE_GVAR: case NODE_LVAR: case NODE_DVAR: case NODE_IVAR: case NODE_CVAR: case NODE_NTH_REF: case NODE_BACK_REF: case NODE_REDO: case NODE_RETRY: case NODE_SELF: case NODE_NIL: case NODE_TRUE: case NODE_FALSE: case NODE_ATTRSET: case NODE_BLOCK_ARG: case NODE_POSTEXE: break; case NODE_ALLOCA: mark_locations_array((VALUE*)obj->as.node.u1.value, obj->as.node.u3.cnt); ptr = (VALUE)obj->as.node.u2.node; goto again; default: /* unlisted NODE */ if (is_pointer_to_heap(obj->as.node.u1.node)) { gc_mark((VALUE)obj->as.node.u1.node, lev); } if (is_pointer_to_heap(obj->as.node.u2.node)) { gc_mark((VALUE)obj->as.node.u2.node, lev); } if (is_pointer_to_heap(obj->as.node.u3.node)) { gc_mark((VALUE)obj->as.node.u3.node, lev); } } return; /* no need to mark class. */ } gc_mark(obj->as.basic.klass, lev); @@ -988,92 +1255,92 @@ gc_mark_children(ptr, lev) case T_ICLASS: case T_CLASS: case T_MODULE: -mark_tbl(obj->as.klass.m_tbl, lev); -mark_tbl(obj->as.klass.iv_tbl, lev); -ptr = obj->as.klass.super; -goto again; + mark_tbl(obj->as.klass.m_tbl, lev); + mark_tbl(obj->as.klass.iv_tbl, lev); + ptr = obj->as.klass.super; + goto again; case T_ARRAY: -if (FL_TEST(obj, ELTS_SHARED)) { ptr = obj->as.array.aux.shared; goto again; -} -else { long i, len = obj->as.array.len; VALUE *ptr = obj->as.array.ptr; + if (FL_TEST(obj, ELTS_SHARED)) { + ptr = obj->as.array.aux.shared; + goto again; + } + else { + long i, len = obj->as.array.len; + VALUE *ptr = obj->as.array.ptr; for (i=0; i -gc_mark(*ptr++, } -} -break; + for + + } + } + break; < len; i++) { lev); (i=0; i < len; i++) { gc_mark(*ptr++, lev); case T_HASH: -mark_hash(obj->as.hash.tbl, lev); -ptr = obj->as.hash.ifnone; -goto again; + mark_hash(obj->as.hash.tbl, lev); + + ptr = obj->as.hash.ifnone; goto again; case T_STRING: #define STR_ASSOC FL_USER3 /* copied from string.c */ -if (FL_TEST(obj, ELTS_SHARED|STR_ASSOC)) { ptr = obj->as.string.aux.shared; goto again; -} -break; + if (FL_TEST(obj, ELTS_SHARED|STR_ASSOC)) { + ptr = obj->as.string.aux.shared; + goto again; + } + break; case T_DATA: -if (obj->as.data.dmark) (*obj->as.data.dmark)(DATA_PTR(obj)); -break; + if (obj->as.data.dmark) (*obj->as.data.dmark)(DATA_PTR(obj)); + break; case T_OBJECT: -mark_tbl(obj->as.object.iv_tbl, lev); -break; + mark_tbl(obj->as.object.iv_tbl, lev); + break; case case case case case -break; + T_FILE: T_REGEXP: T_FLOAT: T_BIGNUM: T_BLKTAG: break; case T_MATCH: -if (obj->as.match.str) { ptr = obj->as.match.str; goto again; -} -break; + if (obj->as.match.str) { + ptr = obj->as.match.str; + goto again; + } + break; case T_VARMAP: -gc_mark(obj->as.varmap.val, lev); -ptr = (VALUE)obj->as.varmap.next; -goto again; + gc_mark(obj->as.varmap.val, lev); + ptr = (VALUE)obj->as.varmap.next; + goto again; case T_SCOPE: -if (obj->as.scope.local_vars && (obj->as.scope.flags & SCOPE_MALLOC)) { int n = obj->as.scope.local_tbl[0]+1; VALUE *vars = &obj->as.scope.local_vars[-1]; + if (obj->as.scope.local_vars && (obj->as.scope.flags & SCOPE_MALLOC)) { + int n = obj->as.scope.local_tbl[0]+1; + VALUE *vars = &obj->as.scope.local_vars[-1]; while (n--) { -gc_mark(*vars++, lev); } -} -break; + while (n--) { + gc_mark(*vars++, lev); + } + } + break; case T_STRUCT: -{ + + + long len = obj->as.rstruct.len; VALUE *ptr = obj->as.rstruct.ptr; { long len = obj->as.rstruct.len; VALUE *ptr = obj->as.rstruct.ptr; while (len--) { -gc_mark(*ptr++, lev); } -} -break; + while (len--) { + gc_mark(*ptr++, lev); + } + } + break; default: -rb_bug("rb_gc_mark(): unknown data type 0x%lx(0x%lx) %s", obj->as.basic.flags & T_MASK, obj, is_pointer_to_heap(obj) ? "corrupted object" : "non object"); + rb_bug("rb_gc_mark(): unknown data type 0x%lx(0x%lx) %s", + obj->as.basic.flags & T_MASK, obj, + is_pointer_to_heap(obj) ? "corrupted object" : "non object"); } } @@ -1102,22 +1369,55 @@ finalize_list(p) } } +static char* obj_type(int tp) +{ + switch (tp) { + case T_NIL : return "NIL"; + case T_OBJECT : return "OBJECT"; + case T_CLASS : return "CLASS"; + case T_ICLASS : return "ICLASS"; + case T_MODULE : return "MODULE"; + case T_FLOAT : return "FLOAT"; + case T_STRING : return "STRING"; + case T_REGEXP : return "REGEXP"; + case T_ARRAY : return "ARRAY"; + case T_FIXNUM : return "FIXNUM"; + case T_HASH : return "HASH"; + case T_STRUCT : return "STRUCT"; + case T_BIGNUM : return "BIGNUM"; + case T_FILE : return "FILE"; + + case T_TRUE : return "TRUE"; + case T_FALSE : return "FALSE"; + case T_DATA : return "DATA"; + case T_MATCH : return "MATCH"; + case T_SYMBOL : return "SYMBOL"; + + case T_BLKTAG : return "BLKTAG"; + case T_UNDEF : return "UNDEF"; + case T_VARMAP : return "VARMAP"; + case T_SCOPE : return "SCOPE"; + case T_NODE : return "NODE"; + default: return "____"; + } +} + static void free_unused_heaps() { int i, j; for (i = j = 1; j < heaps_used; i++) { -if (heaps[i].limit == 0) { free(heaps[i].membase); heaps_used--; -} -else { if (i != j) { -heaps[j] = heaps[i]; } j++; -} + if (heaps[i].limit == 0) { + free(heaps[i].membase); + heaps_used--; + } + else { + if (i != j) { + heaps[j] = heaps[i]; + } + j++; + } } } @@ -1134,24 +1434,33 @@ gc_sweep() unsigned long live = 0; unsigned long free_min = 0; + + + + + + + + + + unsigned long really_freed = 0; int free_counts[256]; int live_counts[256]; int do_gc_stats = gc_statistics & verbose_gc_stats; for (i = 0; i < heaps_used; i++) { free_min += heaps[i].limit; } free_min = free_min * 0.2; if (free_min < FREE_MIN) free_min = FREE_MIN; if (free_min < heap_free_min) free_min = heap_free_min; if (do_gc_stats) { for (i = 0 ; i< 256; i++) { free_counts[i] = live_counts[i] = 0; } + } if (ruby_in_compile && ruby_parser_stack_on_heap()) { -/* should not reclaim nodes during compilation + /* should not reclaim nodes during compilation if yacc's semantic stack is not allocated on machine stack */ -for (i = 0; i < heaps_used; i++) { p = heaps[i].slot; pend = p + heaps[i].limit; while (p < pend) { -if (!(p->as.basic.flags&FL_MARK) && BUILTIN_TYPE(p) == T_NODE) gc_mark((VALUE)p, 0); -p++; } -} + for (i = 0; i < heaps_used; i++) { + p = heaps[i].slot; pend = p + heaps[i].limit; + while (p < pend) { + if (!(p->as.basic.flags&FL_MARK) && BUILTIN_TYPE(p) == T_NODE) + gc_mark((VALUE)p, 0); + p++; + } + } } mark_source_filename(ruby_sourcefile); @@ -1172,7 +1481,7 @@ gc_sweep() while (p < pend) { if (!(p->as.basic.flags & FL_MARK)) { if (p->as.basic.flags && ((deferred = obj_free((VALUE)p)) || + (((do_gc_stats && really_freed++), deferred = obj_free((VALUE)p)) || ((FL_TEST(p, FL_FINALIZE)) && need_call_final))) { if (!deferred) { p->as.free.flags = T_DEFERRED; @@ -1183,6 +1492,12 @@ gc_sweep() final_list = p; } else { + if (do_gc_stats) { + int obt = p->as.basic.flags & T_MASK; + if (obt) { + free_counts[obt]++; + } + } add_freelist(p); } n++; @@ -1194,6 +1509,9 @@ gc_sweep() else { RBASIC(p)->flags &= ~FL_MARK; live++; + if (do_gc_stats) { + live_counts[RANY((VALUE)p)->as.basic.flags & T_MASK]++; + } } p++; } @@ -1211,15 +1529,29 @@ gc_sweep() } } if (malloc_increase > malloc_limit) { -malloc_limit += (malloc_increase - malloc_limit) * (double)live / (live + freed); -if (malloc_limit < GC_MALLOC_LIMIT) malloc_limit = GC_MALLOC_LIMIT; + malloc_limit += (malloc_increase - malloc_limit) * (double)live / (live + freed); + if (malloc_limit < initial_malloc_limit) malloc_limit = initial_malloc_limit; } malloc_increase = 0; if (freed < free_min) { -add_heap(); + add_heap(); } during_gc = 0; + + + + + + + + + + + + + + if (do_gc_stats) { fprintf(gc_data_file, "objects processed: %.7d\n", live+freed); fprintf(gc_data_file, "live objects : %.7d\n", live); fprintf(gc_data_file, "freelist objects : %.7d\n", freed - really_freed); fprintf(gc_data_file, "freed objects : %.7d\n", really_freed); for(i=0; i<256; i++) { if (free_counts[i]>0 || live_counts[i]>0) { fprintf(gc_data_file, "kept %.7d / freed %.7d objects of type %s\n", live_counts[i], free_counts[i], obj_type(i)); } } } /* clear finalization list */ if (final_list) { deferred_final_list = final_list; @@ -1260,51 +1592,51 @@ obj_free(obj) case T_FIXNUM: case T_TRUE: case T_FALSE: -rb_bug("obj_free() called for broken object"); -break; + + } rb_bug("obj_free() called for broken object"); break; if (FL_TEST(obj, FL_EXIVAR)) { -rb_free_generic_ivar((VALUE)obj); + rb_free_generic_ivar((VALUE)obj); } switch (BUILTIN_TYPE(obj)) { case T_OBJECT: -if (RANY(obj)->as.object.iv_tbl) { st_free_table(RANY(obj)->as.object.iv_tbl); -} -break; + if (RANY(obj)->as.object.iv_tbl) { + st_free_table(RANY(obj)->as.object.iv_tbl); + } + break; case T_MODULE: case T_CLASS: -rb_clear_cache_by_class((VALUE)obj); -st_free_table(RANY(obj)->as.klass.m_tbl); -if (RANY(obj)->as.object.iv_tbl) { st_free_table(RANY(obj)->as.object.iv_tbl); -} -break; + rb_clear_cache_by_class((VALUE)obj); + st_free_table(RANY(obj)->as.klass.m_tbl); + if (RANY(obj)->as.object.iv_tbl) { + st_free_table(RANY(obj)->as.object.iv_tbl); + } + break; case T_STRING: -if (RANY(obj)->as.string.ptr && !FL_TEST(obj, ELTS_SHARED)) { RUBY_CRITICAL(free(RANY(obj)->as.string.ptr)); -} -break; + if (RANY(obj)->as.string.ptr && !FL_TEST(obj, ELTS_SHARED)) { + RUBY_CRITICAL(free(RANY(obj)->as.string.ptr)); + } + break; case T_ARRAY: -if (RANY(obj)->as.array.ptr && !FL_TEST(obj, ELTS_SHARED)) { RUBY_CRITICAL(free(RANY(obj)->as.array.ptr)); -} -break; + if (RANY(obj)->as.array.ptr && !FL_TEST(obj, ELTS_SHARED)) { + RUBY_CRITICAL(free(RANY(obj)->as.array.ptr)); + } + break; case T_HASH: -if (RANY(obj)->as.hash.tbl) { st_free_table(RANY(obj)->as.hash.tbl); -} -break; + if (RANY(obj)->as.hash.tbl) { + st_free_table(RANY(obj)->as.hash.tbl); + } + break; case T_REGEXP: -if (RANY(obj)->as.regexp.ptr) { re_free_pattern(RANY(obj)->as.regexp.ptr); -} -if (RANY(obj)->as.regexp.str) { RUBY_CRITICAL(free(RANY(obj)->as.regexp.str)); -} -break; + if (RANY(obj)->as.regexp.ptr) { + re_free_pattern(RANY(obj)->as.regexp.ptr); + } + if (RANY(obj)->as.regexp.str) { + RUBY_CRITICAL(free(RANY(obj)->as.regexp.str)); + } + break; case T_DATA: if (DATA_PTR(obj)) { if ((long)RANY(obj)->as.data.dfree == -1) { @@ -1317,11 +1649,11 @@ obj_free(obj) } break; case T_MATCH: -if (RANY(obj)->as.match.regs) { re_free_registers(RANY(obj)->as.match.regs); RUBY_CRITICAL(free(RANY(obj)->as.match.regs)); -} -break; + if (RANY(obj)->as.match.regs) { + re_free_registers(RANY(obj)->as.match.regs); + RUBY_CRITICAL(free(RANY(obj)->as.match.regs)); + } + break; case T_FILE: if (RANY(obj)->as.file.fptr) { struct rb_io_t *fptr = RANY(obj)->as.file.fptr; @@ -1332,19 +1664,19 @@ obj_free(obj) } break; case T_ICLASS: -/* iClass shares table with the module */ -break; + /* iClass shares table with the module */ + break; case T_FLOAT: case T_VARMAP: case T_BLKTAG: -break; + break; case T_BIGNUM: -if (RANY(obj)->as.bignum.digits) { RUBY_CRITICAL(free(RANY(obj)->as.bignum.digits)); -} -break; + if (RANY(obj)->as.bignum.digits) { + RUBY_CRITICAL(free(RANY(obj)->as.bignum.digits)); + } + break; case T_NODE: switch (nd_type(obj)) { case NODE_SCOPE: @@ -1359,7 +1691,7 @@ obj_free(obj) break;/* no need to free iv_tbl */ case T_SCOPE: -if (RANY(obj)->as.scope.local_vars && + if (RANY(obj)->as.scope.local_vars && RANY(obj)->as.scope.flags != SCOPE_ALLOCA) { VALUE *vars = RANY(obj)->as.scope.local_vars-1; if (!(RANY(obj)->as.scope.flags & SCOPE_CLONE) && vars[0] == 0) @@ -1370,14 +1702,14 @@ obj_free(obj) break; case T_STRUCT: -if (RANY(obj)->as.rstruct.ptr) { RUBY_CRITICAL(free(RANY(obj)->as.rstruct.ptr)); -} -break; + if (RANY(obj)->as.rstruct.ptr) { + RUBY_CRITICAL(free(RANY(obj)->as.rstruct.ptr)); + } + break; default: -rb_bug("gc_sweep(): unknown data type 0x%lx(0x%lx)", RANY(obj)->as.basic.flags & T_MASK, obj); + rb_bug("gc_sweep(): unknown data type 0x%lx(0x%lx)", + RANY(obj)->as.basic.flags & T_MASK, obj); } return 0; @@ -1407,18 +1739,18 @@ _rb_setjmp:\n\ typedef unsigned long rb_jmp_buf[6]; __asm__ (".align 4\n\ _rb_setjmp:\n\ -pushl%ebp\n\ -movl%esp,%ebp\n\ -movl8(%ebp),%ebp\n\ -movl%eax,(%ebp)\n\ -movl%ebx,4(%ebp)\n\ -movl%ecx,8(%ebp)\n\ -movl%edx,12(%ebp)\n\ -movl%esi,16(%ebp)\n\ -movl%edi,20(%ebp)\n\ -popl%ebp\n\ -xorl%eax,%eax\n\ -ret"); + pushl %ebp\n\ + movl %esp,%ebp\n\ + movl 8(%ebp),%ebp\n\ + movl %eax,(%ebp)\n\ + movl %ebx,4(%ebp)\n\ + movl %ecx,8(%ebp)\n\ + movl %edx,12(%ebp)\n\ + movl %esi,16(%ebp)\n\ + movl %edi,20(%ebp)\n\ + popl %ebp\n\ + xorl %eax,%eax\n\ + ret"); #endif #endif int rb_setjmp (rb_jmp_buf); @@ -1431,41 +1763,50 @@ garbage_collect() struct gc_list *list; struct FRAME * volatile frame; /* gcc 2.7.2.3 -O2 bug?? jmp_buf save_regs_gc_mark; + struct timeval gctv1, gctv2; SET_STACK_END; */ #ifdef HAVE_NATIVETHREAD if (!is_ruby_native_thread()) { -rb_bug("cross-thread violation on rb_gc()"); + rb_bug("cross-thread violation on rb_gc()"); } #endif if (dont_gc || during_gc) { -if (!freelist) { add_heap(); -} -return; + if (!freelist) { + add_heap(); + } + return; } if (during_gc) return; during_gc++; + + + + + + + + if (gc_statistics) { gc_collections++; gettimeofday(&gctv1, NULL); if (verbose_gc_stats) { fprintf(gc_data_file, "Garbage collection started\n"); } } init_mark_stack(); gc_mark((VALUE)ruby_current_node, 0); /* mark frame stack */ for (frame = ruby_frame; frame; frame = frame->prev) { -rb_gc_mark_frame(frame); -if (frame->tmp) { struct FRAME *tmp = frame->tmp; while (tmp) { -rb_gc_mark_frame(tmp); -tmp = tmp->prev; } -} + rb_gc_mark_frame(frame); + if (frame->tmp) { + struct FRAME *tmp = frame->tmp; + while (tmp) { + rb_gc_mark_frame(tmp); + tmp = tmp->prev; + } + } } gc_mark((VALUE)ruby_scope, 0); gc_mark((VALUE)ruby_dyna_vars, 0); if (finalizer_table) { -mark_tbl(finalizer_table, 0); + mark_tbl(finalizer_table, 0); } FLUSH_REGISTER_WINDOWS; @@ -1478,9 +1819,9 @@ garbage_collect() rb_gc_mark_locations(rb_gc_stack_start, (VALUE*)STACK_END + 1); #else if ((VALUE*)STACK_END < rb_gc_stack_start) -rb_gc_mark_locations((VALUE*)STACK_END, rb_gc_stack_start); + rb_gc_mark_locations((VALUE*)STACK_END, rb_gc_stack_start); else -rb_gc_mark_locations(rb_gc_stack_start, (VALUE*)STACK_END + 1); + rb_gc_mark_locations(rb_gc_stack_start, (VALUE*)STACK_END + 1); #endif #ifdef __ia64 /* mark backing store (flushed register window on the stack) */ @@ -1489,13 +1830,13 @@ garbage_collect() #endif #if defined(__human68k__) || defined(__mc68000__) rb_gc_mark_locations((VALUE*)((char*)STACK_END + 2), - (VALUE*)((char*)rb_gc_stack_start + 2)); + (VALUE*)((char*)rb_gc_stack_start + 2)); #endif rb_gc_mark_threads(); /* mark protected global variables */ for (list = global_List; list; list = list->next) { -rb_gc_mark_maybe(*list->varptr); + rb_gc_mark_maybe(*list->varptr); } rb_mark_end_proc(); rb_gc_mark_global_tbl(); @@ -1510,18 +1851,30 @@ garbage_collect() /* gc_mark objects whose marking are not completed*/ do { -while (!MARK_STACK_EMPTY) { if (mark_stack_overflow){ -gc_mark_all(); } else { -gc_mark_rest(); } -} -rb_gc_abort_threads(); + while (!MARK_STACK_EMPTY) { + if (mark_stack_overflow){ + gc_mark_all(); + } + else { + gc_mark_rest(); + } + } + rb_gc_abort_threads(); } while (!MARK_STACK_EMPTY); gc_sweep(); + + + + + + + + + + + + if (gc_statistics) { GC_TIME_TYPE musecs_used; gettimeofday(&gctv2, NULL); musecs_used = ((GC_TIME_TYPE)(gctv2.tv_sec - gctv1.tv_sec) * 1000000) + (gctv2.tv_usec - gctv1.tv_usec); gc_time += musecs_used; if (verbose_gc_stats) { fprintf(gc_data_file, "GC time: %d msec\n", musecs_used / 1000); fflush(gc_data_file); } } } void @@ -1588,8 +1941,8 @@ Init_stack(addr) memset(&m, 0, sizeof(m)); VirtualQuery(&m, &m, sizeof(m)); rb_gc_stack_start = -STACK_UPPER((VALUE *)&m, (VALUE *)m.BaseAddress, (VALUE *)((char *)m.BaseAddress + m.RegionSize) - 1); + STACK_UPPER((VALUE *)&m, (VALUE *)m.BaseAddress, + (VALUE *)((char *)m.BaseAddress + m.RegionSize) - 1); #elif defined(STACK_END_ADDRESS) { extern void *STACK_END_ADDRESS; @@ -1599,24 +1952,24 @@ Init_stack(addr) if (!addr) addr = (void *)&addr; STACK_UPPER(&addr, addr, ++addr); if (rb_gc_stack_start) { -if (STACK_UPPER(&addr, -rb_gc_stack_start > addr, -rb_gc_stack_start < addr)) rb_gc_stack_start = addr; -return; + if (STACK_UPPER(&addr, + rb_gc_stack_start > addr, + rb_gc_stack_start < addr)) + rb_gc_stack_start = addr; + return; } rb_gc_stack_start = addr; #endif #ifdef HAVE_GETRLIMIT { -struct rlimit rlim; + struct rlimit rlim; -if (getrlimit(RLIMIT_STACK, &rlim) == 0) { unsigned int space = rlim.rlim_cur/5; + if (getrlimit(RLIMIT_STACK, &rlim) == 0) { + unsigned int space = rlim.rlim_cur/5; -} + + + if (space > 1024*1024) space = 1024*1024; STACK_LEVEL_MAX = (rlim.rlim_cur - space) / sizeof(VALUE); if (space > 1024*1024) space = 1024*1024; STACK_LEVEL_MAX = (rlim.rlim_cur - space) / sizeof(VALUE); } } #endif } @@ -1652,16 +2005,16 @@ void ruby_init_stack(VALUE *addr } #elif defined _WIN32 { -MEMORY_BASIC_INFORMATION mi; -DWORD size; -DWORD space; -if (VirtualQuery(&mi, &mi, sizeof(mi))) { size = (char *)mi.BaseAddress - (char *)mi.AllocationBase; space = size / 5; if (space > 1024*1024) space = 1024*1024; STACK_LEVEL_MAX = (size - space) / sizeof(VALUE); -} + MEMORY_BASIC_INFORMATION mi; + DWORD size; + + + + + + + + DWORD space; if (VirtualQuery(&mi, &mi, sizeof(mi))) { size = (char *)mi.BaseAddress - (char *)mi.AllocationBase; space = size / 5; if (space > 1024*1024) space = 1024*1024; STACK_LEVEL_MAX = (size - space) / sizeof(VALUE); } } #endif } @@ -1701,8 +2054,9 @@ void Init_heap() { if (!rb_gc_stack_start) { -Init_stack(0); + Init_stack(0); } + set_gc_parameters(); add_heap(); } @@ -1715,7 +2069,7 @@ os_obj_of(of) volatile VALUE v; for (i = 0; i < heaps_used; i++) { -RVALUE *p, *pend; + RVALUE *p, *pend; p = heaps[i].slot; pend = p + heaps[i].limit; for (;p < pend; p++) { @@ -1808,8 +2162,8 @@ add_final(os, block) { rb_warn("ObjectSpace::add_finalizer is deprecated; use define_finalizer"); if (!rb_respond_to(block, rb_intern("call"))) { -rb_raise(rb_eArgError, "wrong type argument %s (should be callable)", - rb_obj_classname(block)); + rb_raise(rb_eArgError, "wrong type argument %s (should be callable)", + rb_obj_classname(block)); } rb_ary_push(finalizers, block); return block; @@ -1864,7 +2218,7 @@ undefine_final(os, obj) VALUE os, obj; { if (finalizer_table) { -st_delete(finalizer_table, (st_data_t*)&obj, 0); + st_delete(finalizer_table, (st_data_t*)&obj, 0); } return obj; } @@ -1888,11 +2242,11 @@ define_final(argc, argv, os) rb_scan_args(argc, argv, "11", &obj, &block); if (argc == 1) { -block = rb_block_proc(); + block = rb_block_proc(); } else if (!rb_respond_to(block, rb_intern("call"))) { -rb_raise(rb_eArgError, "wrong type argument %s (should be callable)", - rb_obj_classname(block)); + rb_raise(rb_eArgError, "wrong type argument %s (should be callable)", + rb_obj_classname(block)); } need_call_final = 1; if (!FL_ABLE(obj)) { @@ -1905,10 +2259,10 @@ define_final(argc, argv, os) OBJ_FREEZE(block); if (!finalizer_table) { -finalizer_table = st_init_numtable(); + finalizer_table = st_init_numtable(); } if (st_lookup(finalizer_table, obj, &table)) { -rb_ary_push(table, block); + rb_ary_push(table, block); } else { table = rb_ary_new3(1, block); @@ -1927,7 +2281,7 @@ rb_gc_copy_finalizer(dest, obj) if (!finalizer_table) return; if (!FL_TEST(obj, FL_FINALIZE)) return; if (st_lookup(finalizer_table, obj, &table)) { -st_insert(finalizer_table, dest, table); + st_insert(finalizer_table, dest, table); } RBASIC(dest)->flags |= FL_FINALIZE; } @@ -1957,18 +2311,18 @@ run_final(obj) args[1] = 0; args[2] = (VALUE)ruby_safe_level; for (i=0; i<RARRAY(finalizers)->len; i++) { -args[0] = RARRAY(finalizers)->ptr[i]; -if (!args[1]) args[1] = rb_ary_new3(1, objid); -rb_protect((VALUE(*)_((VALUE)))run_single_final, (VALUE)args, &status); + + + args[0] = RARRAY(finalizers)->ptr[i]; if (!args[1]) args[1] = rb_ary_new3(1, objid); rb_protect((VALUE(*)_((VALUE)))run_single_final, (VALUE)args, &status); } if (finalizer_table && st_delete(finalizer_table, (st_data_t*)&obj, &table)) { -for (i=0; i<RARRAY(table)->len; i++) { VALUE final = RARRAY(table)->ptr[i]; args[0] = RARRAY(final)->ptr[1]; if (!args[1]) args[1] = rb_ary_new3(1, objid); args[2] = FIX2INT(RARRAY(final)->ptr[0]); rb_protect((VALUE(*)_((VALUE)))run_single_final, (VALUE)args, &status); -} + for (i=0; i<RARRAY(table)->len; i++) { + VALUE final = RARRAY(table)->ptr[i]; + args[0] = RARRAY(final)->ptr[1]; + if (!args[1]) args[1] = rb_ary_new3(1, objid); + args[2] = FIX2INT(RARRAY(final)->ptr[0]); + rb_protect((VALUE(*)_((VALUE)))run_single_final, (VALUE)args, &status); + } } rb_thread_critical = critical_save; } @@ -1980,8 +2334,8 @@ rb_gc_finalize_deferred() deferred_final_list = 0; if (p) { -finalize_list(p); -free_unused_heaps(); + finalize_list(p); + free_unused_heaps(); } } @@ -2061,7 +2415,7 @@ id2ref(obj, objid) if (ptr == Qfalse) return Qfalse; if (ptr == Qnil) return Qnil; if (FIXNUM_P(ptr)) return (VALUE)ptr; ptr = objid ^ FIXNUM_FLAG;/* unset FIXNUM_FLAG */ + ptr = objid ^ FIXNUM_FLAG; /* unset FIXNUM_FLAG */ if ((ptr % sizeof(RVALUE)) == (4 << 2)) { ID symid = ptr / sizeof(RVALUE); @@ -2075,7 +2429,7 @@ id2ref(obj, objid) rb_raise(rb_eRangeError, "0x%lx is not id value", p0); } if (BUILTIN_TYPE(ptr) == 0 || RBASIC(ptr)->klass == 0) { -rb_raise(rb_eRangeError, "0x%lx is recycled object", p0); + rb_raise(rb_eRangeError, "0x%lx is recycled object", p0); } return (VALUE)ptr; } @@ -2166,6 +2520,14 @@ Init_GC() rb_define_singleton_method(rb_mGC, "stress=", gc_stress_set, 1); rb_define_method(rb_mGC, "garbage_collect", rb_gc_start, 0); + + + + + + + + rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, "enable_stats", rb_gc_enable_stats, 0); "disable_stats", rb_gc_disable_stats, 0); "clear_stats", rb_gc_clear_stats, 0); "collections", rb_gc_collections, 0); "time", rb_gc_time, 0); "dump", rb_gc_dump, 0); "log", rb_gc_log, 1); rb_mObSpace = rb_define_module("ObjectSpace"); rb_define_module_function(rb_mObSpace, "each_object", os_each_obj, -1); rb_define_module_function(rb_mObSpace, "garbage_collect", rb_gc_start, 0); @@ -2188,7 +2550,7 @@ Init_GC() + rb_global_variable(&nomem_error); nomem_error = rb_exc_new3(rb_eNoMemError, rb_obj_freeze(rb_str_new2("failed to allocate memory"))); rb_obj_freeze(rb_str_new2("failed to allocate memory"))); OBJ_TAINT(nomem_error); OBJ_FREEZE(nomem_error); 1.26.5.1.10.1.12. 05-better-source-file-tracing.patch diff --git a/eval.c b/eval.c index fb3307c..356226e 100644 --- a/eval.c +++ b/eval.c @@ -1161,7 +1161,7 @@ static VALUE trace_func = 0; static int tracing = 0; static void call_trace_func _((rb_event_t,NODE*,VALUE,ID,VALUE)); -#if 0 +#if 1 #define SET_CURRENT_SOURCE() (ruby_sourcefile = ruby_current_node->nd_file, \ ruby_sourceline = nd_line(ruby_current_node)) #else 1.26.5.1.10.1.13. 16-caller-for-all-threads.patch diff --git a/eval.c b/eval.c index 356226e..a0fdc55 100644 --- a/eval.c +++ b/eval.c @@ -8199,6 +8199,17 @@ rb_f_method_name() } } +/* Hash (Thread => Backtrace) used to collect backtrace for each threads. */ +static VALUE backtrace_for_each_thread; + +static int backtrace_level_for_each_thread; + +static VALUE +switch_thread_context_to_collect_backtrace(rb_thread_t next); + +static VALUE +rb_f_caller_for_all_threads(); + void Init_eval() { @@ -8244,6 +8255,7 @@ Init_eval() rb_define_global_function("fail", rb_f_raise, -1); + rb_define_global_function("caller", rb_f_caller, -1); rb_define_global_function("caller_for_all_threads", rb_f_caller_for_all_threads, -1); rb_define_global_function("exit", rb_f_exit, -1); rb_define_global_function("abort", rb_f_abort, -1); @@ -10599,6 +10611,7 @@ static int th_sig, th_safe; #define RESTORE_RAISE5 #define RESTORE_SIGNAL6 #define RESTORE_EXIT7 +#define RESTORE_BACKTRACE8 extern VALUE *rb_gc_stack_start; #ifdef __ia64 @@ -10705,6 +10718,15 @@ rb_thread_switch(n) } rb_exc_raise(th_raise_exception); break; + case RESTORE_BACKTRACE: + rb_hash_aset(backtrace_for_each_thread, curr_thread->thread, + backtrace(backtrace_level_for_each_thread)); + if (curr_thread != main_thread) { + switch_thread_context_to_collect_backtrace(curr_thread->next); + } else { + /* Circled back to main thread, cycle is complete. */ + } + break; case RESTORE_NORMAL: default: break; @@ -13875,3 +13897,74 @@ rb_throw(tag, val) argv[1] = val; rb_f_throw(2, argv); } + +static VALUE +switch_thread_context_to_collect_backtrace(rb_thread_t next) +{ + if (THREAD_SAVE_CONTEXT(curr_thread)) { + return Qnil; + } + curr_thread = next; + rb_thread_restore_context(next, RESTORE_BACKTRACE); + return Qnil; +} + + +/* + * call-seq: + * caller_for_all_threads(start=1) => array + * + * Returns the current execution stack for all threads + * ---a hash whose keys are thread instances and values + * the thread caller backtrace. + * + * Backtraces are array of hashes indicating location on the + * stack. Hash keys include ``<em>:line</em>'' or ``<em>:file</em>'' + * and ``<em>:method'</em>''. + * + * The optional _start_ parameter + * determines the number of initial stack entries to omit from the + * result. + * + * def a(skip) + * caller_for_all_threads(skip) + * end + * def b(skip) + * a(skip) + * end + * def c(skip) + * b(skip) + * end + * c(0) #=> ["prog:2:in `a'", "prog:5:in `b'", "prog:8:in `c'", "prog:10"] + * c(1) #=> ["prog:5:in `b'", "prog:8:in `c'", "prog:11"] + * c(2) #=> ["prog:8:in `c'", "prog:12"] + * c(3) #=> ["prog:13"] + */ +static VALUE +rb_f_caller_for_all_threads(argc, argv) + int argc; + VALUE *argv; +{ + volatile int critical; + VALUE level; +VALUE result; + + rb_scan_args(argc, argv, "01", &level); + backtrace_level_for_each_thread = NIL_P(level) ? 0 : NUM2INT(level); +if (backtrace_level_for_each_thread < 0) { +rb_raise(rb_eArgError, "negative level (%d)", backtrace_level_for_each_thread); +} + +critical = rb_thread_critical; +rb_thread_critical = Qtrue; + + backtrace_for_each_thread = rb_hash_new(); + switch_thread_context_to_collect_backtrace(main_thread->next); + +result = backtrace_for_each_thread; +backtrace_for_each_thread = Qnil; +backtrace_for_each_thread = 0; + +rb_thread_critical = critical; + return result; +} diff --git a/test/callerforallthreads/test_caller_for_each_thread.rb b/test/callerforallthreads/test_caller_for_each_thread.rb new file mode 100644 index 0000000..6aebaed --- /dev/null +++ b/test/callerforallthreads/test_caller_for_each_thread.rb @@ -0,0 +1,95 @@ +# -*- ruby-indent-level: 4 -*+require 'thread' +require 'test/unit' + +class AClassWithNestedmethods + + def an_ultra_nested_method(skip) + caller_for_all_threads skip + end + + def a_nested_method(skip) + an_ultra_nested_method skip + end + + def a_method(skip=0) + a_nested_method skip + end + +end + +class CallerForEachThreadTest < Test::Unit::TestCase + + def testCollectMeaningfulBacktraceForASingleThread + backtraces = AClassWithNestedmethods.new.a_method + backtrace = backtraces[Thread.current] + assert_not_nil backtrace + assert_equal __FILE__ + ":8:in `an_ultra_nested_method'", backtrace[0] + assert_equal __FILE__ + ":12:in `a_nested_method'", backtrace[1] + assert_equal __FILE__ + ":16:in `a_method'", backtrace[2] + assert_equal __FILE__ + ":24:in `testCollectMeaningfulBacktraceForASingleThread'", + backtrace[3] + end + + def testCanSkipFirstStackEntries + backtraces = AClassWithNestedmethods.new.a_method 2 + backtrace = backtraces[Thread.current] + assert_not_nil backtrace + assert_equal __FILE__ + ":16:in `a_method'", backtrace[0] + assert_equal __FILE__ + ":35:in `testCanSkipFirstStackEntries'", + backtrace[1] + end + + def testCollectMeaningfulBacktraceForMultipleThreads + first_thread = Thread.new do + loop do + Thread.pass + sleep 1 + end + end + + second_thread = Thread.new do + loop do + Thread.pass + sleep 1 + end + end + + backtraces = AClassWithNestedmethods.new.a_method + + backtrace = backtraces[Thread.current] + assert_not_nil backtrace + assert_match __FILE__ + ":8:in `an_ultra_nested_method'", backtrace[0] + assert_match __FILE__ + ":12:in `a_nested_method'", backtrace[1] + assert_equal __FILE__ + ":16:in `a_method'", backtrace[2] + assert_equal __FILE__ + ":58:in `testCollectMeaningfulBacktraceForMultipleThreads'", + backtrace[3] + + backtrace = backtraces[first_thread] + assert_not_nil backtrace + assert_equal __FILE__ + ":47:in `testCollectMeaningfulBacktraceForMultipleThreads'", + backtrace[0] + assert_equal __FILE__ + ":45:in `loop'", + backtrace[1] + assert_equal __FILE__ + ":45:in `testCollectMeaningfulBacktraceForMultipleThreads'", + backtrace[2] + assert_equal __FILE__ + ":44:in `initialize'",backtrace[3] + assert_equal __FILE__ + ":44:in `new'", backtrace[4] + assert_equal __FILE__ + ":44:in `testCollectMeaningfulBacktraceForMultipleThreads'", + backtrace[5] + + backtrace = backtraces[second_thread] + assert_not_nil backtrace + assert_equal __FILE__ + ":53:in `testCollectMeaningfulBacktraceForMultipleThreads'", + backtrace[0] + assert_equal __FILE__ + ":52:in `loop'", backtrace[1] + assert_equal __FILE__ + ":52:in `testCollectMeaningfulBacktraceForMultipleThreads'", + backtrace[2] + assert_equal __FILE__ + ":51:in `initialize'",backtrace[3] + assert_equal __FILE__ + ":51:in `new'", backtrace[4] + assert_equal __FILE__ + ":51:in `testCollectMeaningfulBacktraceForMultipleThreads'", + backtrace[5] + end + +end + 1.26.5.1.10.1.14. 09-track-object-allocation.patch diff --git a/gc.c b/gc.c index 30a1219..5b42b90 100644 --- a/gc.c +++ b/gc.c @@ -96,6 +96,26 @@ static void garbage_collect(); int ruby_gc_stress = 0; +static unsigned long live_objects = 0; +unsigned long rb_os_live_objects() +{ + return live_objects; +} + +#if defined(HAVE_LONG_LONG) +static unsigned LONG_LONG allocated_objects = 0; +unsigned LONG_LONG rb_os_allocated_objects() +{ + return allocated_objects; +} +#else +static unsigned long allocated_objects = 0; +unsigned long rb_os_allocated_objects() +{ + return allocated_objects; +} +#endif + NORETURN(void rb_exc_jump _((VALUE))); void @@ -987,6 +1007,8 @@ rb_newobj() RANY(obj)->file = ruby_sourcefile; RANY(obj)->line = ruby_sourceline; #endif + live_objects++; + allocated_objects++; return obj; } @@ -1825,6 +1847,7 @@ gc_sweep() add_heap(); } during_gc = 0; + live_objects = live; if (do_gc_stats) { fprintf(gc_data_file, "objects processed: %.7d\n", live+freed); @@ -2790,6 +2813,35 @@ rb_obj_id(VALUE obj) return (VALUE)((long)obj|FIXNUM_FLAG); } +/* call-seq: + * ObjectSpace.live_objects => number + * + * Returns the count of objects currently allocated in the system. This goes + * down after the garbage collector runs. + */ +static +VALUE os_live_objects(VALUE self) +{ + return ULONG2NUM(live_objects); +} + +/* call-seq: + * ObjectSpace.allocated_objects => number + * + * Returns the count of objects allocated since the Ruby interpreter has + * started. This number can only increase. To know how many objects are + * currently allocated, use ObjectSpace::live_objects + */ +static +VALUE os_allocated_objects(VALUE self) +{ +#if defined(HAVE_LONG_LONG) + return ULL2NUM(allocated_objects); +#else + return ULONG2NUM(allocated_objects); +#endif +} + /* * The <code>GC</code> module provides an interface to Ruby's mark and * sweep garbage collection mechanism. Some of the underlying methods @@ -2833,6 +2885,9 @@ Init_GC() rb_define_module_function(rb_mObSpace, "finalizers", finals, 0); rb_define_module_function(rb_mObSpace, "call_finalizer", call_final, 1); + + + rb_define_module_function(rb_mObSpace, "live_objects", os_live_objects, 0); rb_define_module_function(rb_mObSpace, "allocated_objects", os_allocated_objects, 0); rb_define_module_function(rb_mObSpace, "define_finalizer", define_final, -1); rb_define_module_function(rb_mObSpace, "undefine_finalizer", undefine_final, 1); diff --git a/intern.h b/intern.h index 1117614..a87661d 100644 --- a/intern.h +++ b/intern.h @@ -274,6 +274,12 @@ void rb_gc_before_fork _((void)); void rb_gc_after_fork _((void)); VALUE rb_gc_allocated_size _((void)); VALUE rb_gc_num_allocations _((void)); +unsigned long rb_os_live_objects _((void)); +#ifdef HAVE_LONG_LONG +unsigned LONG_LONG rb_os_allocated_objects _((void)); +#else +unsigned long rb_os_allocated_objects _((void)); +#endif /* hash.c */ void st_foreach_safe _((struct st_table *, int (*)(ANYARGS), unsigned long)); void rb_hash_foreach _((VALUE, int (*)(ANYARGS), VALUE)); 1.26.5.1.10.1.15. 02-sigvtalrm-fix.patch diff --git a/eval.c b/eval.c index 7886e17..6ff2560 100644 --- a/eval.c +++ b/eval.c @@ -12461,6 +12461,11 @@ rb_thread_start_0(fn, arg, th) curr_thread->next = th; th->priority = curr_thread->priority; th->thgroup = curr_thread->thgroup; +#if defined(HAVE_SETITIMER) || defined(_THREAD_SAFE) + if (!thread_init) { + rb_thread_start_timer(); + } +#endif } START_TIMER(); @@ -13189,7 +13194,9 @@ rb_thread_atfork() main_thread = curr_thread; curr_thread->next = curr_thread; curr_thread->prev = curr_thread; STOP_TIMER(); +#if defined(HAVE_SETITIMER) || defined(_THREAD_SAFE) + rb_thread_stop_timer(); +#endif } 1.26.5.1.10.1.16. 10-expose-heap-slots.patch diff --git a/gc.c b/gc.c index 5b42b90..21b3f6b 100644 --- a/gc.c +++ b/gc.c @@ -690,6 +690,7 @@ static int heaps_used = 0; static int heap_min_slots = 10000; static int heap_slots = 10000; +static int heap_size = 0; static int heap_free_min = 4096; static int heap_slots_increment = 10000; @@ -800,6 +801,21 @@ static void set_gc_parameters() /* * call-seq: + * GC.heap_slots => Integer + * + * Returns the number of heap slots available for object allocations. + * + * GC.heap_slots #=> 10000 + * + */ +VALUE +rb_gc_heap_slots() +{ + return INT2NUM(heap_size); +} + +/* + * call-seq: * GC.dump => nil * * dumps information about the current GC data structures to the GC log file @@ -967,6 +983,7 @@ add_heap() heaps[heaps_used].limit = heap_slots; break; } + heap_size += heap_slots; pend = p + heap_slots; if (lomem == 0 || lomem > p) lomem = p; if (himem < pend) himem = pend; @@ -1828,6 +1845,7 @@ gc_sweep() if (n == heaps[i].limit && freed > free_min) { RVALUE *pp; + heap_size -= n; heaps[i].limit = 0; for (pp = final_list; pp != final; pp = pp->as.free.next) { pp->as.free.flags |= FL_SINGLETON; /* freeing page mark */ @@ -2866,6 +2884,7 @@ Init_GC() rb_define_singleton_method(rb_mGC, "clear_stats", rb_gc_clear_stats, 0); rb_define_singleton_method(rb_mGC, "allocated_size", rb_gc_allocated_size, 0); rb_define_singleton_method(rb_mGC, "num_allocations", rb_gc_num_allocations, 0); + rb_define_singleton_method(rb_mGC, "heap_slots", rb_gc_heap_slots, 0); rb_define_singleton_method(rb_mGC, "collections", rb_gc_collections, 0); rb_define_singleton_method(rb_mGC, "time", rb_gc_time, 0); rb_define_singleton_method(rb_mGC, "dump", rb_gc_dump, 0); diff --git a/intern.h b/intern.h index a87661d..e8f3209 100644 --- a/intern.h +++ b/intern.h @@ -274,6 +274,7 @@ void rb_gc_before_fork _((void)); void rb_gc_after_fork _((void)); VALUE rb_gc_allocated_size _((void)); VALUE rb_gc_num_allocations _((void)); +VALUE rb_gc_heap_slots _((void)); unsigned long rb_os_live_objects _((void)); #ifdef HAVE_LONG_LONG unsigned LONG_LONG rb_os_allocated_objects _((void)); 1.26.5.1.11. p352 1.26.5.1.11.1. railsexpress 1.26.5.1.11.1.1. 07-fork-support-for-gc-logging.patch diff --git a/gc.c b/gc.c index 9ad716f..a3cbe91 100644 --- a/gc.c +++ b/gc.c @@ -223,6 +223,8 @@ static int dont_gc; static int gc_statistics = 0; static GC_TIME_TYPE gc_time = 0; static int gc_collections = 0; +static int verbose_gc_stats = Qfalse; +static FILE* gc_data_file = NULL; static int during_gc; static int need_call_final = 0; static st_table *finalizer_table = 0; @@ -368,9 +370,148 @@ rb_gc_time() #endif } VALUE rb_mGC; +/* + * call-seq: + * GC.enable_trace => true or false + * + * Enables garbage collection tracing, returning <code>true</code> if garbage + * collection tracing was already enabled. + * + * GC.enable_trace #=> false or true + * GC.enable_trace #=> true + * + */ + +VALUE +rb_gc_enable_trace() +{ + int old = verbose_gc_stats; + verbose_gc_stats = Qtrue; + return old; +} + +/* + * call-seq: + * GC.disable_trace => true or false + * + * Disables garbage collection tracing, returning <code>true</code> if garbage + * collection tracing was already disabled. + * + * GC.disable_trace #=> false or true + * GC.disable_trace #=> true + * + */ + +VALUE +rb_gc_disable_trace() +{ + int old = verbose_gc_stats; + verbose_gc_stats = Qfalse; + return old; +} + +char* GC_LOGFILE_IVAR = "@gc_logfile_name"; + +/* + * call-seq: + * GC.log_file(filename=nil, mode="w") => boolean + * + * Changes the GC data log file. Closes the currently open logfile. + * Returns true if the file was successfully opened for + * writing. Returns false if the file could not be opened for + * writing. Returns the name of the current logfile (or nil) if no + * parameter is given. Restores logging to stderr when given nil as + * an argument. + * + * GC.log_file #=> nil + * GC.log_file "/tmp/gc.log" #=> true + * GC.log_file #=> "/tmp/gc.log" + * GC.log_file nil #=> true + * + */ + +VALUE +rb_gc_log_file(int argc, VALUE *argv, VALUE self) +{ + VALUE filename = Qnil; + VALUE mode_str = Qnil; + FILE* f = NULL; + char* mode = "w"; + + VALUE current_logfile_name = rb_iv_get(rb_mGC, GC_LOGFILE_IVAR); + + if (argc==0) + return current_logfile_name; + + rb_scan_args(argc, argv, "02", &filename, &mode_str); + + if (filename == Qnil) { + /* close current logfile and reset logfile to stderr */ + if (gc_data_file != stderr) { + fclose(gc_data_file); + gc_data_file = stderr; + rb_iv_set(rb_mGC, GC_LOGFILE_IVAR, Qnil); + } + return Qtrue; + } + + /* we have a real logfile name */ + filename = StringValue(filename); + + if (rb_equal(current_logfile_name, filename) == Qtrue) { + /* do nothing if we get the file name we're already logging to */ + return Qtrue; + } + + /* get mode for file opening */ + if (mode_str != Qnil) + { + mode = RSTRING(StringValue(mode_str))->ptr; + } + + /* try to open file in given mode */ + if (f = fopen(RSTRING(filename)->ptr, mode)) { + if (gc_data_file != stderr) { + fclose(gc_data_file); + } + gc_data_file = f; + rb_iv_set(rb_mGC, GC_LOGFILE_IVAR, filename); + } else { + return Qfalse; + } + return Qtrue; +} + + +/* + * Called from process.c before a fork. Flushes the gc log file to + * avoid writing the buffered output twice (once in the parent, and + * once in the child). + */ +void +rb_gc_before_fork() +{ + /* flush gc log file */ + fflush(gc_data_file); +} + +/* + * Called from process.c after a fork in the child process. Turns off + * logging, disables GC stats and resets all gc counters and timing + * information. + */ +void +rb_gc_after_fork() +{ + rb_gc_disable_stats(); + rb_gc_clear_stats(); + rb_gc_disable_trace(); + gc_data_file = stderr; + rb_iv_set(rb_mGC, GC_LOGFILE_IVAR, Qnil); +} + static struct gc_list { VALUE *varptr; struct gc_list *next; @@ -477,10 +618,6 @@ static double heap_slots_growth_factor = 1.8; static long initial_malloc_limit = GC_MALLOC_LIMIT; -static int verbose_gc_stats = Qfalse; -static FILE* gc_data_file = NULL; static RVALUE *himem, *lomem; static void set_gc_parameters() @@ -496,6 +633,8 @@ static void set_gc_parameters() if (gc_stats_i > 0) { verbose_gc_stats = Qtrue; } + /* child processes should not inherit RUBY_GC_STATS */ + unsetenv("RUBY_GC_STATS"); } gc_heap_file_ptr = getenv("RUBY_GC_DATA_FILE"); @@ -508,6 +647,8 @@ static void set_gc_parameters() fprintf(stderr, "can't open gc log file %s for writing, using default\n", gc_heap_file_ptr); } + /* child processes should not inherit RUBY_GC_DATA_FILE to avoid clobbering */ + unsetenv("RUBY_GC_DATA_FILE"); } min_slots_ptr = getenv("RUBY_HEAP_MIN_SLOTS"); @@ -2619,6 +2760,9 @@ Init_GC() rb_define_singleton_method(rb_mGC, "dump_file_and_line_info", rb_gc_dump_file_and_line_info, -1); #endif rb_define_singleton_method(rb_mGC, "log", rb_gc_log, 1); + rb_define_singleton_method(rb_mGC, "log_file", rb_gc_log_file, -1); + rb_define_singleton_method(rb_mGC, "enable_trace", rb_gc_enable_trace, 0); + rb_define_singleton_method(rb_mGC, "disable_trace", rb_gc_disable_trace, 0); rb_mObSpace = rb_define_module("ObjectSpace"); rb_define_module_function(rb_mObSpace, "each_object", os_each_obj, -1); diff --git a/intern.h b/intern.h index 950ae9d..99696f1 100644 --- a/intern.h +++ b/intern.h @@ -270,6 +270,8 @@ void rb_gc_call_finalizer_at_exit _((void)); VALUE rb_gc_enable _((void)); VALUE rb_gc_disable _((void)); VALUE rb_gc_start _((void)); +void rb_gc_before_fork _((void)); +void rb_gc_after_fork _((void)); /* hash.c */ void st_foreach_safe _((struct st_table *, int (*)(ANYARGS), unsigned long)); void rb_hash_foreach _((VALUE, int (*)(ANYARGS), VALUE)); diff --git a/process.c b/process.c index 8f6285d..ea28cb8 100644 --- a/process.c +++ b/process.c @@ -1330,6 +1330,8 @@ rb_f_fork(obj) fflush(stderr); #endif + + rb_gc_before_fork(); before_exec(); pid = fork(); after_exec(); @@ -1339,6 +1341,7 @@ rb_f_fork(obj) #ifdef linux after_exec(); #endif + rb_gc_after_fork(); rb_thread_atfork(); if (rb_block_given_p()) { int status; @@ -1574,10 +1577,12 @@ rb_f_system(argc, argv) chfunc = signal(SIGCHLD, SIG_DFL); retry: + rb_gc_before_fork(); before_exec(); pid = fork(); if (pid == 0) { /* child process */ + rb_gc_after_fork(); rb_thread_atfork(); rb_protect(proc_exec_args, (VALUE)&earg, NULL); _exit(127); 1.26.5.1.11.1.2. 08-track-malloc-size.patch diff --git a/gc.c b/gc.c index a3cbe91..30a1219 100644 --- a/gc.c +++ b/gc.c @@ -79,6 +79,17 @@ void *alloca (); static unsigned long malloc_increase = 0; static unsigned long malloc_limit = GC_MALLOC_LIMIT; + +#ifdef HAVE_LONG_LONG +static unsigned LONG_LONG gc_allocated_size = 0; +static unsigned LONG_LONG gc_num_allocations = 0; +#else +static unsigned long gc_allocated_size = 0; +static unsigned long gc_num_allocations = 0; +#endif +static int gc_statistics = 0; + + static void run_final(); static VALUE nomem_error; static void garbage_collect(); @@ -163,6 +174,11 @@ ruby_xmalloc(size) } malloc_increase += size; + if (gc_statistics) { + gc_allocated_size += size; +gc_num_allocations += 1; + } + return mem; } @@ -220,7 +236,6 @@ ruby_xfree(x) extern int ruby_in_compile; static int dont_gc; -static int gc_statistics = 0; static GC_TIME_TYPE gc_time = 0; static int gc_collections = 0; static int verbose_gc_stats = Qfalse; @@ -329,11 +344,55 @@ rb_gc_clear_stats() { gc_collections = 0; gc_time = 0; + gc_allocated_size = 0; + gc_num_allocations = 0; return Qnil; } /* * call-seq: + * GC.allocated_size => Integer + * + * Returns the size of memory (in bytes) allocated since GC statistics collection + * was enabled. + * + * GC.allocated_size #=> 35 + * + */ +VALUE +rb_gc_allocated_size() +{ +#if HAVE_LONG_LONG + return ULL2NUM(gc_allocated_size); +#else + return ULONG2NUM(gc_allocated_size); +#endif +} + +/* + * call-seq: + * GC.num_allocations => Integer + * + * Returns the number of memory allocations since GC statistics collection + * was enabled. + * + * GC.num_allocations #=> 150 + * + */ +VALUE +rb_gc_num_allocations() +{ +#if HAVE_LONG_LONG + return ULL2NUM(gc_num_allocations); +#else + return ULONG2NUM(gc_num_allocations); +#endif +} + +/* + +/* + * call-seq: * GC.collections => Integer * * Returns the number of garbage collections performed while GC statistics collection @@ -2753,6 +2812,8 @@ Init_GC() rb_define_singleton_method(rb_mGC, "enable_stats", rb_gc_enable_stats, 0); rb_define_singleton_method(rb_mGC, "disable_stats", rb_gc_disable_stats, 0); rb_define_singleton_method(rb_mGC, "clear_stats", rb_gc_clear_stats, 0); + rb_define_singleton_method(rb_mGC, "allocated_size", rb_gc_allocated_size, 0); + rb_define_singleton_method(rb_mGC, "num_allocations", rb_gc_num_allocations, 0); rb_define_singleton_method(rb_mGC, "collections", rb_gc_collections, 0); rb_define_singleton_method(rb_mGC, "time", rb_gc_time, 0); rb_define_singleton_method(rb_mGC, "dump", rb_gc_dump, 0); diff --git a/intern.h b/intern.h index 99696f1..1117614 100644 --- a/intern.h +++ b/intern.h @@ -272,6 +272,8 @@ VALUE rb_gc_disable _((void)); VALUE rb_gc_start _((void)); void rb_gc_before_fork _((void)); void rb_gc_after_fork _((void)); +VALUE rb_gc_allocated_size _((void)); +VALUE rb_gc_num_allocations _((void)); /* hash.c */ void st_foreach_safe _((struct st_table *, int (*)(ANYARGS), unsigned long)); void rb_hash_foreach _((VALUE, int (*)(ANYARGS), VALUE)); 1.26.5.1.11.1.3. 13-add-trace-stats-enabled-methods.patch diff --git a/gc.c b/gc.c index 57740d2..2c34932 100644 --- a/gc.c +++ b/gc.c @@ -350,6 +350,22 @@ rb_gc_disable_stats() /* * call-seq: + * GC.stats_enabled? => true or false + * + * Check whether GC stats have been enabled. + * + * GC.stats_enabled? #=> false or true + * + */ + +VALUE +rb_gc_stats_enabled() +{ + return gc_statistics ? Qtrue : Qfalse; +} + +/* + * call-seq: * GC.clear_stats => nil * * Clears garbage collection statistics, returning nil. This resets the number @@ -491,6 +507,22 @@ rb_gc_disable_trace() return old; } +/* + * call-seq: + * GC.trace_enabled? => true or false + * + * Check whether GC tracing has been enabled. + * + * GC.trace_enabled? #=> false or true + * + */ + +VALUE +rb_gc_trace_enabled() +{ + return verbose_gc_stats ? Qtrue : Qfalse; +} + char* GC_LOGFILE_IVAR = "@gc_logfile_name"; /* @@ -2887,6 +2919,7 @@ Init_GC() rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, + rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, @@ -2902,6 +2935,7 @@ Init_GC() rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, + rb_define_singleton_method(rb_mGC, "enable_stats", rb_gc_enable_stats, 0); "disable_stats", rb_gc_disable_stats, 0); "stats_enabled?", rb_gc_stats_enabled, 0); "clear_stats", rb_gc_clear_stats, 0); "allocated_size", rb_gc_allocated_size, 0); "num_allocations", rb_gc_num_allocations, 0); "log_file", rb_gc_log_file, -1); "enable_trace", rb_gc_enable_trace, 0); "disable_trace", rb_gc_disable_trace, 0); "trace_enabled?", rb_gc_trace_enabled, 0); rb_mObSpace = rb_define_module("ObjectSpace"); rb_define_module_function(rb_mObSpace, "each_object", os_each_obj, -1); 1.26.5.1.11.1.4. 12-heap-slot-size.patch diff --git a/gc.c b/gc.c index 7db1ef6..57740d2 100644 --- a/gc.c +++ b/gc.c @@ -2891,6 +2891,7 @@ Init_GC() rb_define_singleton_method(rb_mGC, "allocated_size", rb_gc_allocated_size, 0); rb_define_singleton_method(rb_mGC, "num_allocations", rb_gc_num_allocations, 0); rb_define_singleton_method(rb_mGC, "heap_slots", rb_gc_heap_slots, 0); + rb_define_const(rb_mGC, "HEAP_SLOT_SIZE", INT2FIX(sizeof(RVALUE))); rb_define_singleton_method(rb_mGC, "collections", rb_gc_collections, 0); rb_define_singleton_method(rb_mGC, "time", rb_gc_time, 0); rb_define_singleton_method(rb_mGC, "dump", rb_gc_dump, 0); 1.26.5.1.11.1.5. 14-track-live-dataset-size.patch diff --git a/gc.c b/gc.c index 2c34932..0ce7e68 100644 --- a/gc.c +++ b/gc.c @@ -89,6 +89,7 @@ static unsigned long gc_num_allocations = 0; #endif static int gc_statistics = 0; +static unsigned long heap_slots_live_after_last_gc = 0; static void run_final(); static VALUE nomem_error; @@ -465,6 +466,23 @@ rb_gc_time() #endif } +/* + * call-seq: + * GC.heap_slots_live_after_last_gc => Integer + * + * Returns the number of heap slots which were live after the last garbage collection. + * + * GC.heap_slots_live_after_last_gc #=> 231223 + * + */ +VALUE +rb_gc_heap_slots_live_after_last_gc() +{ + return ULONG2NUM(heap_slots_live_after_last_gc); +} + + + VALUE rb_mGC; /* @@ -1903,6 +1921,7 @@ gc_sweep() } during_gc = 0; live_objects = live; + heap_slots_live_after_last_gc = live; if (do_gc_stats) { fprintf(gc_data_file, "objects processed: %.7d\n", live+freed); @@ -2924,6 +2943,7 @@ Init_GC() rb_define_singleton_method(rb_mGC, "allocated_size", rb_gc_allocated_size, 0); rb_define_singleton_method(rb_mGC, "num_allocations", rb_gc_num_allocations, 0); rb_define_singleton_method(rb_mGC, "heap_slots", rb_gc_heap_slots, 0); + rb_define_singleton_method(rb_mGC, "heap_slots_live_after_last_gc", rb_gc_heap_slots_live_after_last_gc, 0); rb_define_const(rb_mGC, "HEAP_SLOT_SIZE", INT2FIX(sizeof(RVALUE))); rb_define_singleton_method(rb_mGC, "collections", rb_gc_collections, 0); rb_define_singleton_method(rb_mGC, "time", rb_gc_time, 0); 1.26.5.1.11.1.6. 15-add-object-size-information-to-heap-dump.patch diff --git a/gc.c b/gc.c index 0ce7e68..53450bf 100644 --- a/gc.c +++ b/gc.c @@ -953,9 +953,21 @@ rb_gc_dump_file_and_line_info(int argc, VALUE *argv) if (!p->as.basic.klass) { fprintf(f, "__unknown__"); } else { fprintf(f, rb_obj_classname((VALUE)p)); + fprintf(f, "%s", rb_obj_classname((VALUE)p)); } } + /* print object size for some known object types */ + switch (TYPE(p)) { + case T_STRING: + fprintf(f, ":%lu", RSTRING(p)->len); + break; + case T_ARRAY: + fprintf(f, ":%lu", RARRAY(p)->len); + break; + case T_HASH: + fprintf(f, ":%d", RHASH(p)->tbl->num_entries); + break; + } } fprintf(f, "\n"); } @@ -1924,10 +1936,10 @@ gc_sweep() heap_slots_live_after_last_gc = live; if (do_gc_stats) { fprintf(gc_data_file, "objects processed: %.7d\n", live+freed); fprintf(gc_data_file, "live objects : %.7d\n", live); fprintf(gc_data_file, "freelist objects : %.7d\n", freed - really_freed); fprintf(gc_data_file, "freed objects : %.7d\n", really_freed); fprintf(gc_data_file, "objects processed: %.7lu\n", live+freed); fprintf(gc_data_file, "live objects : %.7lu\n", live); fprintf(gc_data_file, "freelist objects : %.7lu\n", freed - really_freed); fprintf(gc_data_file, "freed objects : %.7lu\n", really_freed); for(i=0; i<256; i++) { if (free_counts[i]>0 || live_counts[i]>0) { fprintf(gc_data_file, @@ -2258,7 +2270,7 @@ garbage_collect() gc_time += musecs_used; + + + + if (verbose_gc_stats) { fprintf(gc_data_file, "GC time: %d msec\n", musecs_used / 1000); fprintf(gc_data_file, "GC time: %ld msec\n", (long)(musecs_used / 1000)); fflush(gc_data_file); } + } 1.26.5.1.11.1.7. 11-fix-heap-size-growth-logic.patch diff --git a/gc.c b/gc.c index 21b3f6b..7db1ef6 100644 --- a/gc.c +++ b/gc.c @@ -694,6 +694,7 @@ static int heap_size = 0; static static +static static int heap_free_min = 4096; int heap_slots_increment = 10000; int initial_heap_slots_increment = 10000; double heap_slots_growth_factor = 1.8; static long initial_malloc_limit = GC_MALLOC_LIMIT; @@ -771,14 +772,13 @@ static void set_gc_parameters() if (verbose_gc_stats) { fprintf(gc_data_file, "RUBY_HEAP_SLOTS_INCREMENT=%s\n", heap_slots_incr_ptr); } if (heap_slots_incr_i > 0) { heap_slots_increment = heap_slots_incr_i; } + heap_slots_increment = heap_slots_incr_i; + initial_heap_slots_increment = heap_slots_increment; } heap_slots_growth_factor_ptr = getenv("RUBY_HEAP_SLOTS_GROWTH_FACTOR"); if (heap_slots_growth_factor_ptr != NULL) { double heap_slots_growth_factor_d = atoi(heap_slots_growth_factor_ptr); + double heap_slots_growth_factor_d = atof(heap_slots_growth_factor_ptr); if (verbose_gc_stats) { fprintf(gc_data_file, "RUBY_HEAP_SLOTS_GROWTH_FACTOR=%s\n", heap_slots_growth_factor_ptr); } @@ -988,8 +988,13 @@ add_heap() if (lomem == 0 || lomem > p) lomem = p; if (himem < pend) himem = pend; heaps_used++; heap_slots += heap_slots_increment; heap_slots_increment *= heap_slots_growth_factor; + if (heaps_used == 1) + heap_slots = initial_heap_slots_increment; + else { + heap_slots_increment *= heap_slots_growth_factor; + heap_slots += heap_slots_increment; + } + if (heap_slots <= 0) heap_slots = heap_min_slots; while (p < pend) { @@ -1879,6 +1884,7 @@ gc_sweep() live_counts[i], free_counts[i], obj_type(i)); } } + rb_gc_dump(); fflush(gc_data_file); } 1.26.5.1.11.1.8. 04-display-full-stack-trace.patch diff --git a/eval.c b/eval.c index 6ff2560..fb3307c 100644 --- a/eval.c +++ b/eval.c @@ -1325,8 +1325,8 @@ error_print() int truncate = eclass == rb_eSysStackError; #define -#define -#define +#define +#define TRACE_MAX (TRACE_HEAD+TRACE_TAIL+5) TRACE_HEAD 8 TRACE_TAIL 5 TRACE_HEAD 100 TRACE_TAIL 100 ep = RARRAY(errat); for (i=1; i<ep->len; i++) { 1.26.5.1.11.1.9. 06-heap-dump-support.patch diff --git a/configure.in b/configure.in index 62b34a8..4be088c 100644 --- a/configure.in +++ b/configure.in @@ -1595,6 +1595,14 @@ fi LDFLAGS="-L. $LDFLAGS" AC_SUBST(ARCHFILE) +dnl enable gc debugging +AC_ARG_ENABLE(gcdebug, + [ --enable-gcdebug build garbage collector with debugging enabled. ], + [enable_gcdebug=$enableval]) +if test "$enable_gcdebug" = 'yes'; then + AC_DEFINE(GC_DEBUG, 1) +fi + dnl build rdoc index if requested RDOCTARGET="" AC_ARG_ENABLE(install-doc, diff --git a/gc.c b/gc.c index ab71d22..9ad716f 100644 --- a/gc.c +++ b/gc.c @@ -411,7 +411,6 @@ rb_gc_unregister_address(addr) } } -#undef GC_DEBUG void rb_global_variable(var) @@ -602,6 +601,85 @@ rb_gc_dump() return Qnil; } + +static char* obj_type(int tp); + +#ifdef GC_DEBUG +/* + * call-seq: + * GC.dump_file_and_line_info(String, boolean) => nil + * + * dumps information on which currently allocated object was created by which file and on which line + * + * GC.dump_file_and_line_info(String, boolean) #=> nil + * + * The second parameter specifies whether class names should be included in the dump. + * Note that including class names will allocate additional string objects on the heap. + * + */ + +VALUE +rb_gc_dump_file_and_line_info(int argc, VALUE *argv) +{ + VALUE filename, str, include_classnames = Qnil; + char *fname = NULL; + char *klass = NULL; + FILE* f = NULL; + int i,n = 0; + + rb_scan_args(argc, argv, "11", &filename, &include_classnames); + + str = StringValue(filename); + fname = RSTRING(str)->ptr; + f = fopen(fname, "w"); + + for (i = 0; i < heaps_used; i++) { + RVALUE *p, *pend; + + p = heaps[i].slot; pend = p + heaps[i].limit; + for (;p < pend; p++) { + if (p->as.basic.flags) { + fprintf(f, "%s:%s:%d", obj_type(p->as.basic.flags & T_MASK), p->file, p->line); + // rb_obj_classname will create objects on the heap, we need a better solution + if (include_classnames == Qtrue) { + /* write the class */ + fprintf(f, ":"); + switch (TYPE(p)) { + case T_NONE: + fprintf(f, "__none__"); + break; + case T_BLKTAG: + fprintf(f, "__blktag__"); + break; + case T_UNDEF: + fprintf(f, "__undef__"); + break; + case T_VARMAP: + fprintf(f, "__varmap__"); + break; + case T_SCOPE: + fprintf(f, "__scope__"); + break; + case T_NODE: + fprintf(f, "__node__"); + break; + default: + if (!p->as.basic.klass) { + fprintf(f, "__unknown__"); + } else { + fprintf(f, rb_obj_classname((VALUE)p)); + } + } + } + fprintf(f, "\n"); + } + } + } + fclose(f); + return Qnil; +} +#endif + /* * call-seq: * GC.log String => String @@ -1066,6 +1144,11 @@ gc_mark(ptr, lev) if (obj->as.basic.flags & FL_MARK) return; /* already marked */ obj->as.basic.flags |= FL_MARK; +#ifdef GC_DEBUG + /* mark our new reference point for sourcefile objects */ + mark_source_filename(RANY(obj)->file); +#endif + if (lev > GC_LEVEL_MAX || (lev == 0 && ruby_stack_check())) { if (!mark_stack_overflow) { if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) { @@ -1104,6 +1187,11 @@ gc_mark_children(ptr, lev) if (obj->as.basic.flags & FL_MARK) return; /* already marked */ obj->as.basic.flags |= FL_MARK; +#ifdef GC_DEBUG + /* mark our new reference point for sourcefile objects */ + mark_source_filename(RANY(obj)->file); +#endif + marking: if (FL_TEST(obj, FL_EXIVAR)) { rb_mark_generic_ivar(ptr); @@ -1550,6 +1638,7 @@ gc_sweep() live_counts[i], free_counts[i], obj_type(i)); } } + fflush(gc_data_file); } /* clear finalization list */ @@ -2526,6 +2615,9 @@ Init_GC() rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, +#ifdef GC_DEBUG + rb_define_singleton_method(rb_mGC, +#endif rb_define_singleton_method(rb_mGC, "collections", rb_gc_collections, 0); "time", rb_gc_time, 0); "dump", rb_gc_dump, 0); "dump_file_and_line_info", rb_gc_dump_file_and_line_info, -1); "log", rb_gc_log, 1); rb_mObSpace = rb_define_module("ObjectSpace"); 1.26.5.1.11.1.10. 01-ignore-generated-files.patch diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..00c347a --- /dev/null +++ b/.gitignore @@ -0,0 +1,95 @@ +.ext +.installed.list +.rbconfig.time +Makefile +autom4te.cache/ +config.h +config.status +configure +ext/Win32API/Makefile +ext/bigdecimal/Makefile +ext/curses/Makefile +ext/dbm/Makefile +ext/digest/Makefile +ext/digest/bubblebabble/Makefile +ext/digest/md5/Makefile +ext/digest/rmd160/Makefile +ext/digest/sha1/Makefile +ext/digest/sha2/Makefile +ext/dl/Makefile +ext/dl/call.func +ext/dl/callback.func +ext/dl/cbtable.func +ext/dl/dlconfig.h +ext/dl/dlconfig.rb +ext/enumerator/Makefile +ext/etc/Makefile +ext/fcntl/Makefile +ext/gdbm/Makefile +ext/iconv/Makefile +ext/io/wait/Makefile +ext/nkf/Makefile +ext/openssl/Makefile +ext/openssl/extconf.h +ext/pty/Makefile +ext/racc/cparse/Makefile +ext/readline/Makefile +ext/sdbm/Makefile +ext/socket/Makefile +ext/stringio/Makefile +ext/strscan/Makefile +ext/syck/Makefile +ext/syslog/Makefile +ext/thread/Makefile +ext/tk/Makefile +ext/tk/tkutil/Makefile +ext/win32ole/Makefile +ext/win32ole/.document +ext/zlib/Makefile +largefile.h +miniruby +parse.c +rbconfig.rb +ruby +enc.mk +ext/bigdecimal/extconf.h +ext/continuation/ +ext/coverage/ +ext/curses/extconf.h +ext/dbm/extconf.h +ext/digest/bubblebabble/extconf.h +ext/digest/extconf.h +ext/digest/md5/extconf.h +ext/digest/rmd160/extconf.h +ext/digest/sha1/extconf.h +ext/digest/sha2/extconf.h +ext/dl/callback.h +ext/dl/extconf.h +ext/etc/extconf.h +ext/fcntl/extconf.h +ext/fiber/ +ext/iconv/extconf.h +ext/io/wait/extconf.h +ext/json/ +ext/nkf/extconf.h +ext/pty/extconf.h +ext/racc/cparse/extconf.h +ext/readline/extconf.h +ext/ripper/ +ext/sdbm/extconf.h +ext/socket/constants.h +ext/socket/extconf.h +ext/stringio/extconf.h +ext/strscan/extconf.h +ext/syck/extconf.h +ext/syslog/extconf.h +ext/tk/extconf.h +ext/tk/tkutil/extconf.h +ext/zlib/extconf.h +miniprelude.c +prelude.c +revision.h +*.dylib +*.log +*.dSYM +patches-ruby* 1.26.5.1.11.1.11. 03-railsbench-gc-patch.patch diff --git a/gc.c b/gc.c index fa45cd1..ab71d22 100644 --- a/gc.c +++ b/gc.c @@ -22,8 +22,16 @@ #include <setjmp.h> #include <sys/types.h> +#ifdef _WIN32 +#include <string.h> +#else +#include <strings.h> +#endif + #ifdef HAVE_SYS_TIME_H #include <sys/time.h> +#elif defined(_WIN32) +#include <time.h> #endif #ifdef HAVE_SYS_RESOURCE_H @@ -42,7 +50,6 @@ void rb_io_fptr_finalize _((struct rb_io_t*)); #ifdef __CYGWIN__ int _setjmp(), _longjmp(); #endif /* Make alloca work the best possible way. */ #ifdef __GNUC__ # ifndef atarist @@ -86,12 +93,12 @@ rb_memerror() rb_thread_t th = rb_curr_thread; if (!nomem_error || -(rb_thread_raised_p(th, RAISED_NOMEMORY) && rb_safe_level() < 4)) { -fprintf(stderr, "[FATAL] failed to allocate memory\n"); -exit(1); + (rb_thread_raised_p(th, RAISED_NOMEMORY) && rb_safe_level() < 4)) { + fprintf(stderr, "[FATAL] failed to allocate memory\n"); + exit(1); } if (rb_thread_raised_p(th, RAISED_NOMEMORY)) { -rb_exc_jump(nomem_error); + rb_exc_jump(nomem_error); } rb_thread_raised_set(th, RAISED_NOMEMORY); rb_exc_raise(nomem_error); @@ -139,7 +146,7 @@ ruby_xmalloc(size) void *mem; if (size < 0) { -rb_raise(rb_eNoMemError, "negative allocation size (or too big)"); + rb_raise(rb_eNoMemError, "negative allocation size (or too big)"); } if (size == 0) size = 1; @@ -148,11 +155,11 @@ ruby_xmalloc(size) } RUBY_CRITICAL(mem = malloc(size)); if (!mem) { -garbage_collect(); -RUBY_CRITICAL(mem = malloc(size)); -if (!mem) { rb_memerror(); -} + garbage_collect(); + RUBY_CRITICAL(mem = malloc(size)); + if (!mem) { + rb_memerror(); + } } malloc_increase += size; @@ -179,17 +186,17 @@ ruby_xrealloc(ptr, size) void *mem; if (size < 0) { -rb_raise(rb_eArgError, "negative re-allocation size"); + rb_raise(rb_eArgError, "negative re-allocation size"); } if (!ptr) return xmalloc(size); if (size == 0) size = 1; if (ruby_gc_stress) garbage_collect(); RUBY_CRITICAL(mem = realloc(ptr, size)); if (!mem) { -garbage_collect(); -RUBY_CRITICAL(mem = realloc(ptr, size)); -if (!mem) { rb_memerror(); + garbage_collect(); + RUBY_CRITICAL(mem = realloc(ptr, size)); + if (!mem) { + rb_memerror(); } } malloc_increase += size; @@ -202,11 +209,20 @@ ruby_xfree(x) void *x; { if (x) -RUBY_CRITICAL(free(x)); + RUBY_CRITICAL(free(x)); } +#if HAVE_LONG_LONG +#define GC_TIME_TYPE LONG_LONG +#else +#define GC_TIME_TYPE long +#endif + extern int ruby_in_compile; static int dont_gc; +static int gc_statistics = 0; +static GC_TIME_TYPE gc_time = 0; +static int gc_collections = 0; static int during_gc; static int need_call_final = 0; static st_table *finalizer_table = 0; @@ -241,7 +257,7 @@ rb_gc_enable() * Disables garbage collection, returning <code>true</code> if garbage * collection was already disabled. * - * GC.disable #=> false + * GC.disable #=> false or true * GC.disable #=> true * */ @@ -255,6 +271,104 @@ rb_gc_disable() return old; } +/* + * call-seq: + * GC.enable_stats => true or false + * + * Enables garbage collection statistics, returning <code>true</code> if garbage + * collection statistics was already enabled. + * + * GC.enable_stats #=> false or true + * GC.enable_stats #=> true + * + */ + +VALUE +rb_gc_enable_stats() +{ + int old = gc_statistics; + gc_statistics = Qtrue; + return old; +} + +/* + * call-seq: + * GC.disable_stats => true or false + * + * Disables garbage collection statistics, returning <code>true</code> if garbage + * collection statistics was already disabled. + * + * GC.disable_stats #=> false or true + * GC.disable_stats #=> true + * + */ + +VALUE +rb_gc_disable_stats() +{ + int old = gc_statistics; + gc_statistics = Qfalse; + return old; +} + +/* + * call-seq: + * GC.clear_stats => nil + * + * Clears garbage collection statistics, returning nil. This resets the number + * of collections (GC.collections) and the time used (GC.time) to 0. + * + * GC.clear_stats #=> nil + * + */ + +VALUE +rb_gc_clear_stats() +{ + gc_collections = 0; + gc_time = 0; + return Qnil; +} + +/* + * call-seq: + * GC.collections => Integer + * + * Returns the number of garbage collections performed while GC statistics collection + * was enabled. + * + * GC.collections #=> 35 + * + */ + +VALUE +rb_gc_collections() +{ + return INT2NUM(gc_collections); +} + +/* + * call-seq: + * GC.time => Integer + * + * Returns the time spent during garbage collection while GC statistics collection + * was enabled (in micro seconds). + * + * GC.time #=> 20000 + * + */ + +VALUE +rb_gc_time() +{ +#if HAVE_LONG_LONG + return LL2NUM(gc_time); +#else + return LONG2NUM(gc_time); +#endif +} + + VALUE rb_mGC; static struct gc_list { @@ -281,19 +395,19 @@ rb_gc_unregister_address(addr) struct gc_list *tmp = global_List; if (tmp->varptr == addr) { -global_List = tmp->next; -RUBY_CRITICAL(free(tmp)); -return; + global_List = tmp->next; + RUBY_CRITICAL(free(tmp)); + return; } while (tmp->next) { -if (tmp->next->varptr == addr) { struct gc_list *t = tmp->next; + if (tmp->next->varptr == addr) { + struct gc_list *t = tmp->next; -} -tmp + + + + + tmp->next = tmp->next->next; RUBY_CRITICAL(free(t)); break; = tmp->next; tmp->next = tmp->next->next; RUBY_CRITICAL(free(t)); break; } tmp = tmp->next; } } @@ -312,26 +426,26 @@ rb_global_variable(var) typedef struct RVALUE { union { -struct { unsigned long flags;/* always 0 for freed obj */ struct RVALUE *next; -} free; -struct RBasic basic; -struct RObject object; -struct RClass klass; -struct RFloat flonum; -struct RString string; -struct RArray array; -struct RRegexp regexp; -struct RHash hash; -struct RData data; -struct RStruct rstruct; -struct RBignum bignum; -struct RFile file; -struct RNode node; -struct RMatch match; -struct RVarmap varmap; -struct SCOPE scope; + struct { + unsigned long flags; /* always 0 for freed obj */ + struct RVALUE *next; + } free; + struct RBasic basic; + struct RObject object; + struct RClass klass; + struct RFloat flonum; + struct RString string; + struct RArray array; + struct RRegexp regexp; + struct RHash hash; + struct RData data; + struct RStruct rstruct; + struct RBignum bignum; + struct RFile file; + struct RNode node; + struct RMatch match; + struct RVarmap varmap; + struct SCOPE scope; } as; #ifdef GC_DEBUG char *file; @@ -346,7 +460,7 @@ typedef struct RVALUE { static RVALUE *freelist = 0; static RVALUE *deferred_final_list = 0; -#define HEAPS_INCREMENT 10 +static int heaps_increment = 10; static struct heaps_slot { void *membase; RVALUE *slot; @@ -355,45 +469,197 @@ static struct heaps_slot { static int heaps_length = 0; static int heaps_used = 0; -#define HEAP_MIN_SLOTS 10000 -static int heap_slots = HEAP_MIN_SLOTS; +static int heap_min_slots = 10000; +static int heap_slots = 10000; -#define FREE_MIN 4096 +static int heap_free_min = 4096; +static int heap_slots_increment = 10000; +static double heap_slots_growth_factor = 1.8; + +static long initial_malloc_limit = GC_MALLOC_LIMIT; + +static int verbose_gc_stats = Qfalse; + +static FILE* gc_data_file = NULL; static RVALUE *himem, *lomem; +static void set_gc_parameters() +{ + char *gc_stats_ptr, *min_slots_ptr, *free_min_ptr, *heap_slots_incr_ptr, + *heap_incr_ptr, *malloc_limit_ptr, *gc_heap_file_ptr, *heap_slots_growth_factor_ptr; + + gc_data_file = stderr; + + gc_stats_ptr = getenv("RUBY_GC_STATS"); + if (gc_stats_ptr != NULL) { + int gc_stats_i = atoi(gc_stats_ptr); + if (gc_stats_i > 0) { + verbose_gc_stats = Qtrue; + } + } + + gc_heap_file_ptr = getenv("RUBY_GC_DATA_FILE"); + if (gc_heap_file_ptr != NULL) { + FILE* data_file = fopen(gc_heap_file_ptr, "w"); + if (data_file != NULL) { + gc_data_file = data_file; + } + else { + fprintf(stderr, + "can't open gc log file %s for writing, using default\n", gc_heap_file_ptr); + } + } + + min_slots_ptr = getenv("RUBY_HEAP_MIN_SLOTS"); + if (min_slots_ptr != NULL) { + int min_slots_i = atoi(min_slots_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_MIN_SLOTS=%s\n", min_slots_ptr); + } + if (min_slots_i > 0) { + heap_slots = min_slots_i; + heap_min_slots = min_slots_i; + } + } + + free_min_ptr = getenv("RUBY_HEAP_FREE_MIN"); + if (free_min_ptr != NULL) { + int free_min_i = atoi(free_min_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_FREE_MIN=%s\n", free_min_ptr); + } + if (free_min_i > 0) { + heap_free_min = free_min_i; + } + } + + heap_incr_ptr = getenv("RUBY_HEAP_INCREMENT"); + if (heap_incr_ptr != NULL) { + int heap_incr_i = atoi(heap_incr_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_INCREMENT=%s\n", heap_incr_ptr); + } + if (heap_incr_i > 0) { + heaps_increment = heap_incr_i; + } + } + + heap_slots_incr_ptr = getenv("RUBY_HEAP_SLOTS_INCREMENT"); + if (heap_slots_incr_ptr != NULL) { + int heap_slots_incr_i = atoi(heap_slots_incr_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_SLOTS_INCREMENT=%s\n", heap_slots_incr_ptr); + } + if (heap_slots_incr_i > 0) { + heap_slots_increment = heap_slots_incr_i; + } + } + + heap_slots_growth_factor_ptr = getenv("RUBY_HEAP_SLOTS_GROWTH_FACTOR"); + if (heap_slots_growth_factor_ptr != NULL) { + double heap_slots_growth_factor_d = atoi(heap_slots_growth_factor_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_SLOTS_GROWTH_FACTOR=%s\n", heap_slots_growth_factor_ptr); + } + if (heap_slots_growth_factor_d > 0) { + heap_slots_growth_factor = heap_slots_growth_factor_d; + } + } + + malloc_limit_ptr = getenv("RUBY_GC_MALLOC_LIMIT"); + if (malloc_limit_ptr != NULL) { + int malloc_limit_i = atol(malloc_limit_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_GC_MALLOC_LIMIT=%s\n", malloc_limit_ptr); + } + if (malloc_limit_i > 0) { + initial_malloc_limit = malloc_limit_i; + } + } +} + +/* + * call-seq: + * GC.dump => nil + * + * dumps information about the current GC data structures to the GC log file + * + * GC.dump #=> nil + * + */ + +VALUE +rb_gc_dump() +{ + int i; + + for (i = 0; i < heaps_used; i++) { + int heap_size = heaps[i].limit; + fprintf(gc_data_file, "HEAP[%2d]: size=%7d\n", i, heap_size); + } + + return Qnil; +} + +/* + * call-seq: + * GC.log String => String + * + * Logs string to the GC data file and returns it. + * + * GC.log "manual GC call" #=> "manual GC call" + * + */ + +VALUE +rb_gc_log(self, original_str) + VALUE self, original_str; +{ + if (original_str == Qnil) { + fprintf(gc_data_file, "\n"); + } + else { + VALUE str = StringValue(original_str); + char *p = RSTRING(str)->ptr; + fprintf(gc_data_file, "%s\n", p); + } + return original_str; +} + + static void add_heap() { RVALUE *p, *pend; if (heaps_used == heaps_length) { -/* Realloc heaps */ -struct heaps_slot *p; -int length; -heaps_length += HEAPS_INCREMENT; -length = heaps_length*sizeof(struct heaps_slot); -RUBY_CRITICAL( if (heaps_used > 0) { -p = (struct heaps_slot *)realloc(heaps, length); -if (p) heaps = p; } else { -p = heaps = (struct heaps_slot *)malloc(length); }); -if (p == 0) rb_memerror(); + /* Realloc heaps */ + struct heaps_slot *p; + int length; + + heaps_length += heaps_increment; + length = heaps_length*sizeof(struct heaps_slot); + RUBY_CRITICAL( + if (heaps_used > 0) { + p = (struct heaps_slot *)realloc(heaps, length); + if (p) heaps = p; + } + else { + p = heaps = (struct heaps_slot *)malloc(length); + }); + if (p == 0) rb_memerror(); } for (;;) { -RUBY_CRITICAL(p = (RVALUE*)malloc(sizeof(RVALUE)*(heap_slots+1))); -if (p == 0) { if (heap_slots == HEAP_MIN_SLOTS) { -rb_memerror(); } heap_slots = HEAP_MIN_SLOTS; continue; -} + RUBY_CRITICAL(p = (RVALUE*)malloc(sizeof(RVALUE)*(heap_slots+1))); + if (p == 0) { + if (heap_slots == heap_min_slots) { + rb_memerror(); + } + heap_slots = heap_min_slots; + continue; + } heaps[heaps_used].membase = p; if ((VALUE)p % sizeof(RVALUE) == 0) heap_slots += 1; @@ -401,25 +667,26 @@ add_heap() p = (RVALUE*)((VALUE)p + sizeof(RVALUE) - ((VALUE)p % sizeof(RVALUE))); heaps[heaps_used].slot = p; heaps[heaps_used].limit = heap_slots; -break; + break; } pend = p + heap_slots; if (lomem == 0 || lomem > p) lomem = p; if (himem < pend) himem = pend; heaps_used++; heap_slots *= 1.8; if (heap_slots <= 0) heap_slots = HEAP_MIN_SLOTS; + heap_slots += heap_slots_increment; + heap_slots_increment *= heap_slots_growth_factor; + if (heap_slots <= 0) heap_slots = heap_min_slots; while (p < pend) { -p->as.free.flags = 0; -p->as.free.next = freelist; -freelist = p; -p++; + p->as.free.flags = 0; + p->as.free.next = freelist; + freelist = p; + p++; } } #define RANY(o) ((RVALUE*)(o)) -int +int rb_during_gc() { return during_gc; @@ -431,7 +698,7 @@ rb_newobj() VALUE obj; if (during_gc) -rb_bug("object allocation during garbage collection phase"); + rb_bug("object allocation during garbage collection phase"); if (ruby_gc_stress || !freelist) garbage_collect(); @@ -580,13 +847,13 @@ rb_source_filename(f) st_data_t name; if (!st_lookup(source_filenames, (st_data_t)f, &name)) { -long len = strlen(f) + 1; -char *ptr = ALLOC_N(char, len + 1); -name = (st_data_t)ptr; -*ptr++ = 0; -MEMCPY(ptr, f, char, len); -st_add_direct(source_filenames, (st_data_t)ptr, name); -return ptr; + long len = strlen(f) + 1; + char *ptr = ALLOC_N(char, len + 1); + name = (st_data_t)ptr; + *ptr++ = 0; + MEMCPY(ptr, f, char, len); + st_add_direct(source_filenames, (st_data_t)ptr, name); + return ptr; } return (char *)name + 1; } @@ -596,7 +863,7 @@ mark_source_filename(f) char *f; { if (f) { -f[-1] = 1; + f[-1] = 1; } } @@ -605,12 +872,12 @@ sweep_source_filename(key, value) char *key, *value; { if (*value) { -*value = 0; -return ST_CONTINUE; + *value = 0; + return ST_CONTINUE; } else { -free(value); -return ST_DELETE; + free(value); + return ST_DELETE; } } @@ -625,14 +892,14 @@ gc_mark_all() init_mark_stack(); for (i = 0; i < heaps_used; i++) { -p = heaps[i].slot; pend = p + heaps[i].limit; -while (p < pend) { if ((p->as.basic.flags & FL_MARK) && -(p->as.basic.flags != FL_MARK)) { -gc_mark_children((VALUE)p, 0); } p++; -} + p = heaps[i].slot; pend = p + heaps[i].limit; + while (p < pend) { + if ((p->as.basic.flags & FL_MARK) && + (p->as.basic.flags != FL_MARK)) { + gc_mark_children((VALUE)p, 0); + } + p++; + } } } @@ -647,8 +914,8 @@ gc_mark_rest() init_mark_stack(); while(p != tmp_arry){ -p--; -gc_mark_children(*p, 0); + + p--; gc_mark_children(*p, 0); } } @@ -665,9 +932,9 @@ is_pointer_to_heap(ptr) /* check if p looks like a pointer */ for (i=0; i < heaps_used; i++) { -heap_org = heaps[i].slot; -if (heap_org <= p && p < heap_org + heaps[i].limit) return Qtrue; + heap_org = heaps[i].slot; + if (heap_org <= p && p < heap_org + heaps[i].limit) + return Qtrue; } return Qfalse; } @@ -680,10 +947,10 @@ mark_locations_array(x, n) VALUE v; while (n--) { v = *x; -if (is_pointer_to_heap((void *)v)) { gc_mark(v, 0); -} -x++; + if (is_pointer_to_heap((void *)v)) { + gc_mark(v, 0); + } + x++; } } @@ -780,7 +1047,7 @@ rb_gc_mark_maybe(obj) VALUE obj; { if (is_pointer_to_heap((void *)obj)) { -gc_mark(obj, 0); + gc_mark(obj, 0); } } @@ -828,7 +1095,7 @@ gc_mark_children(ptr, lev) { register RVALUE *obj = RANY(ptr); + goto marking;/* skip */ goto marking; /* skip */ again: obj = RANY(ptr); @@ -839,148 +1106,148 @@ gc_mark_children(ptr, lev) marking: if (FL_TEST(obj, FL_EXIVAR)) { -rb_mark_generic_ivar(ptr); + rb_mark_generic_ivar(ptr); } switch (obj->as.basic.flags & T_MASK) { case T_NIL: case T_FIXNUM: -rb_bug("rb_gc_mark() called for broken object"); -break; + rb_bug("rb_gc_mark() called for broken object"); + break; case T_NODE: -mark_source_filename(obj->as.node.nd_file); -switch (nd_type(obj)) { - case NODE_IF:/* 1,2,3 */ - case NODE_FOR: - case NODE_ITER: - case NODE_CREF: - case NODE_WHEN: - case NODE_MASGN: - case NODE_RESCUE: - case NODE_RESBODY: - case NODE_CLASS: gc_mark((VALUE)obj->as.node.u2.node, lev); /* fall through */ - case NODE_BLOCK:/* 1,3 */ - case NODE_ARRAY: - case NODE_DSTR: - case NODE_DXSTR: - case NODE_DREGX: - case NODE_DREGX_ONCE: - case NODE_FBODY: - case NODE_ENSURE: - case NODE_CALL: - case NODE_DEFS: - case NODE_OP_ASGN1: gc_mark((VALUE)obj->as.node.u1.node, lev); /* fall through */ - case NODE_SUPER:/* 3 */ - case NODE_FCALL: - case NODE_DEFN: - case NODE_NEWLINE: ptr = (VALUE)obj->as.node.u3.node; goto again; - case NODE_WHILE:/* 1,2 */ - case NODE_UNTIL: - case NODE_AND: - case NODE_OR: - case NODE_CASE: - case NODE_SCLASS: - case NODE_DOT2: - case NODE_DOT3: - case NODE_FLIP2: - case NODE_FLIP3: - case NODE_MATCH2: - case NODE_MATCH3: - case NODE_OP_ASGN_OR: - case NODE_OP_ASGN_AND: - case NODE_MODULE: - case NODE_ALIAS: - case NODE_VALIAS: - case NODE_ARGS: gc_mark((VALUE)obj->as.node.u1.node, lev); /* fall through */ - case NODE_METHOD:/* 2 */ - case NODE_NOT: - case NODE_GASGN: - case NODE_LASGN: - case NODE_DASGN: - case NODE_DASGN_CURR: - case NODE_IASGN: - case NODE_CVDECL: - case NODE_CVASGN: - case NODE_COLON3: - case NODE_OPT_N: - case NODE_EVSTR: - case NODE_UNDEF: ptr = (VALUE)obj->as.node.u2.node; goto again; - case NODE_HASH:/* 1 */ - case NODE_LIT: - case NODE_STR: - case NODE_XSTR: - case NODE_DEFINED: - case NODE_MATCH: - case NODE_RETURN: - case NODE_BREAK: - case NODE_NEXT: - case NODE_YIELD: - case NODE_COLON2: - case NODE_SPLAT: - case NODE_TO_ARY: - case NODE_SVALUE: ptr = (VALUE)obj->as.node.u1.node; goto again; - case NODE_SCOPE:/* 2,3 */ - case NODE_BLOCK_PASS: - case NODE_CDECL: gc_mark((VALUE)obj->as.node.u3.node, lev); ptr = (VALUE)obj->as.node.u2.node; goto again; - case NODE_ZARRAY:/* - */ - case NODE_ZSUPER: - case NODE_CFUNC: - case NODE_VCALL: - case NODE_GVAR: - case NODE_LVAR: - case NODE_DVAR: - case NODE_IVAR: - case NODE_CVAR: - case NODE_NTH_REF: - case NODE_BACK_REF: - case NODE_REDO: - case NODE_RETRY: - case NODE_SELF: - case NODE_NIL: - case NODE_TRUE: - case NODE_FALSE: - case NODE_ATTRSET: - case NODE_BLOCK_ARG: - case NODE_POSTEXE: break; - case NODE_ALLOCA: mark_locations_array((VALUE*)obj->as.node.u1.value, - obj->as.node.u3.cnt); ptr = (VALUE)obj->as.node.u2.node; goto again; - default:/* unlisted NODE */ if (is_pointer_to_heap(obj->as.node.u1.node)) { -gc_mark((VALUE)obj->as.node.u1.node, lev); } if (is_pointer_to_heap(obj->as.node.u2.node)) { -gc_mark((VALUE)obj->as.node.u2.node, lev); } if (is_pointer_to_heap(obj->as.node.u3.node)) { -gc_mark((VALUE)obj->as.node.u3.node, lev); } -} -return;/* no need to mark class. */ + mark_source_filename(obj->as.node.nd_file); + switch (nd_type(obj)) { + case NODE_IF: /* 1,2,3 */ + case NODE_FOR: + case NODE_ITER: + case NODE_CREF: + case NODE_WHEN: + case NODE_MASGN: + case NODE_RESCUE: + case NODE_RESBODY: + case NODE_CLASS: + gc_mark((VALUE)obj->as.node.u2.node, lev); + /* fall through */ + case NODE_BLOCK: /* 1,3 */ + case NODE_ARRAY: + case NODE_DSTR: + case NODE_DXSTR: + case NODE_DREGX: + case NODE_DREGX_ONCE: + case NODE_FBODY: + case NODE_ENSURE: + case NODE_CALL: + case NODE_DEFS: + case NODE_OP_ASGN1: + gc_mark((VALUE)obj->as.node.u1.node, lev); + /* fall through */ + case NODE_SUPER: /* 3 */ + case NODE_FCALL: + case NODE_DEFN: + case NODE_NEWLINE: + ptr = (VALUE)obj->as.node.u3.node; + goto again; + + case NODE_WHILE: /* 1,2 */ + case NODE_UNTIL: + case NODE_AND: + case NODE_OR: + case NODE_CASE: + case NODE_SCLASS: + case NODE_DOT2: + case NODE_DOT3: + case NODE_FLIP2: + case NODE_FLIP3: + case NODE_MATCH2: + case NODE_MATCH3: + case NODE_OP_ASGN_OR: + case NODE_OP_ASGN_AND: + case NODE_MODULE: + case NODE_ALIAS: + case NODE_VALIAS: + case NODE_ARGS: + gc_mark((VALUE)obj->as.node.u1.node, lev); + /* fall through */ + case NODE_METHOD: /* 2 */ + case NODE_NOT: + case NODE_GASGN: + case NODE_LASGN: + case NODE_DASGN: + case NODE_DASGN_CURR: + case NODE_IASGN: + case NODE_CVDECL: + case NODE_CVASGN: + case NODE_COLON3: + case NODE_OPT_N: + case NODE_EVSTR: + case NODE_UNDEF: + ptr = (VALUE)obj->as.node.u2.node; + goto again; + + case NODE_HASH: /* 1 */ + case NODE_LIT: + case NODE_STR: + case NODE_XSTR: + case NODE_DEFINED: + case NODE_MATCH: + case NODE_RETURN: + case NODE_BREAK: + case NODE_NEXT: + case NODE_YIELD: + case NODE_COLON2: + case NODE_SPLAT: + case NODE_TO_ARY: + case NODE_SVALUE: + ptr = (VALUE)obj->as.node.u1.node; + goto again; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + case NODE_SCOPE: /* 2,3 */ case NODE_BLOCK_PASS: case NODE_CDECL: gc_mark((VALUE)obj->as.node.u3.node, lev); ptr = (VALUE)obj->as.node.u2.node; goto again; case NODE_ZARRAY: /* - */ case NODE_ZSUPER: case NODE_CFUNC: case NODE_VCALL: case NODE_GVAR: case NODE_LVAR: case NODE_DVAR: case NODE_IVAR: case NODE_CVAR: case NODE_NTH_REF: case NODE_BACK_REF: case NODE_REDO: case NODE_RETRY: case NODE_SELF: case NODE_NIL: case NODE_TRUE: case NODE_FALSE: case NODE_ATTRSET: case NODE_BLOCK_ARG: case NODE_POSTEXE: break; case NODE_ALLOCA: mark_locations_array((VALUE*)obj->as.node.u1.value, obj->as.node.u3.cnt); ptr = (VALUE)obj->as.node.u2.node; goto again; default: /* unlisted NODE */ if (is_pointer_to_heap(obj->as.node.u1.node)) { gc_mark((VALUE)obj->as.node.u1.node, lev); } if (is_pointer_to_heap(obj->as.node.u2.node)) { gc_mark((VALUE)obj->as.node.u2.node, lev); } if (is_pointer_to_heap(obj->as.node.u3.node)) { gc_mark((VALUE)obj->as.node.u3.node, lev); } } return; /* no need to mark class. */ } gc_mark(obj->as.basic.klass, lev); @@ -988,92 +1255,92 @@ gc_mark_children(ptr, lev) case T_ICLASS: case T_CLASS: case T_MODULE: -mark_tbl(obj->as.klass.m_tbl, lev); -mark_tbl(obj->as.klass.iv_tbl, lev); -ptr = obj->as.klass.super; -goto again; + mark_tbl(obj->as.klass.m_tbl, lev); + mark_tbl(obj->as.klass.iv_tbl, lev); + ptr = obj->as.klass.super; + goto again; case T_ARRAY: -if (FL_TEST(obj, ELTS_SHARED)) { ptr = obj->as.array.aux.shared; goto again; -} -else { long i, len = obj->as.array.len; VALUE *ptr = obj->as.array.ptr; + if (FL_TEST(obj, ELTS_SHARED)) { + ptr = obj->as.array.aux.shared; + goto again; + } + else { + long i, len = obj->as.array.len; + VALUE *ptr = obj->as.array.ptr; for (i=0; i -gc_mark(*ptr++, } -} -break; + for + + } + } + break; < len; i++) { lev); (i=0; i < len; i++) { gc_mark(*ptr++, lev); case T_HASH: -mark_hash(obj->as.hash.tbl, lev); -ptr = obj->as.hash.ifnone; -goto again; + mark_hash(obj->as.hash.tbl, lev); + + ptr = obj->as.hash.ifnone; goto again; case T_STRING: #define STR_ASSOC FL_USER3 /* copied from string.c */ -if (FL_TEST(obj, ELTS_SHARED|STR_ASSOC)) { ptr = obj->as.string.aux.shared; goto again; -} -break; + if (FL_TEST(obj, ELTS_SHARED|STR_ASSOC)) { + ptr = obj->as.string.aux.shared; + goto again; + } + break; case T_DATA: -if (obj->as.data.dmark) (*obj->as.data.dmark)(DATA_PTR(obj)); -break; + if (obj->as.data.dmark) (*obj->as.data.dmark)(DATA_PTR(obj)); + break; case T_OBJECT: -mark_tbl(obj->as.object.iv_tbl, lev); -break; + mark_tbl(obj->as.object.iv_tbl, lev); + break; case case case case case -break; + T_FILE: T_REGEXP: T_FLOAT: T_BIGNUM: T_BLKTAG: break; case T_MATCH: -if (obj->as.match.str) { ptr = obj->as.match.str; goto again; -} -break; + if (obj->as.match.str) { + ptr = obj->as.match.str; + goto again; + } + break; case T_VARMAP: -gc_mark(obj->as.varmap.val, lev); -ptr = (VALUE)obj->as.varmap.next; -goto again; + gc_mark(obj->as.varmap.val, lev); + ptr = (VALUE)obj->as.varmap.next; + goto again; case T_SCOPE: -if (obj->as.scope.local_vars && (obj->as.scope.flags & SCOPE_MALLOC)) { int n = obj->as.scope.local_tbl[0]+1; VALUE *vars = &obj->as.scope.local_vars[-1]; + if (obj->as.scope.local_vars && (obj->as.scope.flags & SCOPE_MALLOC)) { + int n = obj->as.scope.local_tbl[0]+1; + VALUE *vars = &obj->as.scope.local_vars[-1]; while (n--) { -gc_mark(*vars++, lev); } -} -break; + while (n--) { + gc_mark(*vars++, lev); + } + } + break; case T_STRUCT: -{ + + + long len = obj->as.rstruct.len; VALUE *ptr = obj->as.rstruct.ptr; { long len = obj->as.rstruct.len; VALUE *ptr = obj->as.rstruct.ptr; while (len--) { -gc_mark(*ptr++, lev); } -} -break; + while (len--) { + gc_mark(*ptr++, lev); + } + } + break; default: -rb_bug("rb_gc_mark(): unknown data type 0x%lx(0x%lx) %s", obj->as.basic.flags & T_MASK, obj, is_pointer_to_heap(obj) ? "corrupted object" : "non object"); + rb_bug("rb_gc_mark(): unknown data type 0x%lx(0x%lx) %s", + obj->as.basic.flags & T_MASK, obj, + is_pointer_to_heap(obj) ? "corrupted object" : "non object"); } } @@ -1102,22 +1369,55 @@ finalize_list(p) } } +static char* obj_type(int tp) +{ + switch (tp) { + case T_NIL : return "NIL"; + case T_OBJECT : return "OBJECT"; + case T_CLASS : return "CLASS"; + case T_ICLASS : return "ICLASS"; + case T_MODULE : return "MODULE"; + case T_FLOAT : return "FLOAT"; + case T_STRING : return "STRING"; + case T_REGEXP : return "REGEXP"; + case T_ARRAY : return "ARRAY"; + case T_FIXNUM : return "FIXNUM"; + case T_HASH : return "HASH"; + case T_STRUCT : return "STRUCT"; + case T_BIGNUM : return "BIGNUM"; + case T_FILE : return "FILE"; + + case T_TRUE : return "TRUE"; + case T_FALSE : return "FALSE"; + case T_DATA : return "DATA"; + case T_MATCH : return "MATCH"; + case T_SYMBOL : return "SYMBOL"; + + case T_BLKTAG : return "BLKTAG"; + case T_UNDEF : return "UNDEF"; + case T_VARMAP : return "VARMAP"; + case T_SCOPE : return "SCOPE"; + case T_NODE : return "NODE"; + default: return "____"; + } +} + static void free_unused_heaps() { int i, j; for (i = j = 1; j < heaps_used; i++) { -if (heaps[i].limit == 0) { free(heaps[i].membase); heaps_used--; -} -else { if (i != j) { -heaps[j] = heaps[i]; } j++; -} + if (heaps[i].limit == 0) { + free(heaps[i].membase); + heaps_used--; + } + else { + if (i != j) { + heaps[j] = heaps[i]; + } + j++; + } } } @@ -1134,24 +1434,33 @@ gc_sweep() unsigned long live = 0; unsigned long free_min = 0; + + + + + + + + + + unsigned long really_freed = 0; int free_counts[256]; int live_counts[256]; int do_gc_stats = gc_statistics & verbose_gc_stats; for (i = 0; i < heaps_used; i++) { free_min += heaps[i].limit; } free_min = free_min * 0.2; if (free_min < FREE_MIN) free_min = FREE_MIN; if (free_min < heap_free_min) free_min = heap_free_min; if (do_gc_stats) { for (i = 0 ; i< 256; i++) { free_counts[i] = live_counts[i] = 0; } + } if (ruby_in_compile && ruby_parser_stack_on_heap()) { -/* should not reclaim nodes during compilation + /* should not reclaim nodes during compilation if yacc's semantic stack is not allocated on machine stack */ -for (i = 0; i < heaps_used; i++) { p = heaps[i].slot; pend = p + heaps[i].limit; while (p < pend) { -if (!(p->as.basic.flags&FL_MARK) && BUILTIN_TYPE(p) == T_NODE) gc_mark((VALUE)p, 0); -p++; } -} + for (i = 0; i < heaps_used; i++) { + p = heaps[i].slot; pend = p + heaps[i].limit; + while (p < pend) { + if (!(p->as.basic.flags&FL_MARK) && BUILTIN_TYPE(p) == T_NODE) + gc_mark((VALUE)p, 0); + p++; + } + } } mark_source_filename(ruby_sourcefile); @@ -1172,7 +1481,7 @@ gc_sweep() while (p < pend) { if (!(p->as.basic.flags & FL_MARK)) { if (p->as.basic.flags && ((deferred = obj_free((VALUE)p)) || + (((do_gc_stats && really_freed++), deferred = obj_free((VALUE)p)) || ((FL_TEST(p, FL_FINALIZE)) && need_call_final))) { if (!deferred) { p->as.free.flags = T_DEFERRED; @@ -1183,6 +1492,12 @@ gc_sweep() final_list = p; } else { + if (do_gc_stats) { + int obt = p->as.basic.flags & T_MASK; + if (obt) { + free_counts[obt]++; + } + } add_freelist(p); } n++; @@ -1194,6 +1509,9 @@ gc_sweep() else { RBASIC(p)->flags &= ~FL_MARK; live++; + if (do_gc_stats) { + live_counts[RANY((VALUE)p)->as.basic.flags & T_MASK]++; + } } p++; } @@ -1211,15 +1529,29 @@ gc_sweep() } } if (malloc_increase > malloc_limit) { -malloc_limit += (malloc_increase - malloc_limit) * (double)live / (live + freed); -if (malloc_limit < GC_MALLOC_LIMIT) malloc_limit = GC_MALLOC_LIMIT; + malloc_limit += (malloc_increase - malloc_limit) * (double)live / (live + freed); + if (malloc_limit < initial_malloc_limit) malloc_limit = initial_malloc_limit; } malloc_increase = 0; if (freed < free_min) { -add_heap(); + add_heap(); } during_gc = 0; + + + + + + + + + + + + + + if (do_gc_stats) { fprintf(gc_data_file, "objects processed: %.7d\n", live+freed); fprintf(gc_data_file, "live objects : %.7d\n", live); fprintf(gc_data_file, "freelist objects : %.7d\n", freed - really_freed); fprintf(gc_data_file, "freed objects : %.7d\n", really_freed); for(i=0; i<256; i++) { if (free_counts[i]>0 || live_counts[i]>0) { fprintf(gc_data_file, "kept %.7d / freed %.7d objects of type %s\n", live_counts[i], free_counts[i], obj_type(i)); } } } /* clear finalization list */ if (final_list) { deferred_final_list = final_list; @@ -1260,51 +1592,51 @@ obj_free(obj) case T_FIXNUM: case T_TRUE: case T_FALSE: -rb_bug("obj_free() called for broken object"); -break; + + } rb_bug("obj_free() called for broken object"); break; if (FL_TEST(obj, FL_EXIVAR)) { -rb_free_generic_ivar((VALUE)obj); + rb_free_generic_ivar((VALUE)obj); } switch (BUILTIN_TYPE(obj)) { case T_OBJECT: -if (RANY(obj)->as.object.iv_tbl) { st_free_table(RANY(obj)->as.object.iv_tbl); -} -break; + if (RANY(obj)->as.object.iv_tbl) { + st_free_table(RANY(obj)->as.object.iv_tbl); + } + break; case T_MODULE: case T_CLASS: -rb_clear_cache_by_class((VALUE)obj); -st_free_table(RANY(obj)->as.klass.m_tbl); -if (RANY(obj)->as.object.iv_tbl) { st_free_table(RANY(obj)->as.object.iv_tbl); -} -break; + rb_clear_cache_by_class((VALUE)obj); + st_free_table(RANY(obj)->as.klass.m_tbl); + if (RANY(obj)->as.object.iv_tbl) { + st_free_table(RANY(obj)->as.object.iv_tbl); + } + break; case T_STRING: -if (RANY(obj)->as.string.ptr && !FL_TEST(obj, ELTS_SHARED)) { RUBY_CRITICAL(free(RANY(obj)->as.string.ptr)); -} -break; + if (RANY(obj)->as.string.ptr && !FL_TEST(obj, ELTS_SHARED)) { + RUBY_CRITICAL(free(RANY(obj)->as.string.ptr)); + } + break; case T_ARRAY: -if (RANY(obj)->as.array.ptr && !FL_TEST(obj, ELTS_SHARED)) { RUBY_CRITICAL(free(RANY(obj)->as.array.ptr)); -} -break; + if (RANY(obj)->as.array.ptr && !FL_TEST(obj, ELTS_SHARED)) { + RUBY_CRITICAL(free(RANY(obj)->as.array.ptr)); + } + break; case T_HASH: -if (RANY(obj)->as.hash.tbl) { st_free_table(RANY(obj)->as.hash.tbl); -} -break; + if (RANY(obj)->as.hash.tbl) { + st_free_table(RANY(obj)->as.hash.tbl); + } + break; case T_REGEXP: -if (RANY(obj)->as.regexp.ptr) { re_free_pattern(RANY(obj)->as.regexp.ptr); -} -if (RANY(obj)->as.regexp.str) { RUBY_CRITICAL(free(RANY(obj)->as.regexp.str)); -} -break; + if (RANY(obj)->as.regexp.ptr) { + re_free_pattern(RANY(obj)->as.regexp.ptr); + } + if (RANY(obj)->as.regexp.str) { + RUBY_CRITICAL(free(RANY(obj)->as.regexp.str)); + } + break; case T_DATA: if (DATA_PTR(obj)) { if ((long)RANY(obj)->as.data.dfree == -1) { @@ -1317,11 +1649,11 @@ obj_free(obj) } break; case T_MATCH: -if (RANY(obj)->as.match.regs) { re_free_registers(RANY(obj)->as.match.regs); RUBY_CRITICAL(free(RANY(obj)->as.match.regs)); -} -break; + if (RANY(obj)->as.match.regs) { + re_free_registers(RANY(obj)->as.match.regs); + RUBY_CRITICAL(free(RANY(obj)->as.match.regs)); + } + break; case T_FILE: if (RANY(obj)->as.file.fptr) { struct rb_io_t *fptr = RANY(obj)->as.file.fptr; @@ -1332,19 +1664,19 @@ obj_free(obj) } break; case T_ICLASS: -/* iClass shares table with the module */ -break; + /* iClass shares table with the module */ + break; case T_FLOAT: case T_VARMAP: case T_BLKTAG: -break; + break; case T_BIGNUM: -if (RANY(obj)->as.bignum.digits) { RUBY_CRITICAL(free(RANY(obj)->as.bignum.digits)); -} -break; + if (RANY(obj)->as.bignum.digits) { + RUBY_CRITICAL(free(RANY(obj)->as.bignum.digits)); + } + break; case T_NODE: switch (nd_type(obj)) { case NODE_SCOPE: @@ -1359,7 +1691,7 @@ obj_free(obj) break;/* no need to free iv_tbl */ case T_SCOPE: -if (RANY(obj)->as.scope.local_vars && + if (RANY(obj)->as.scope.local_vars && RANY(obj)->as.scope.flags != SCOPE_ALLOCA) { VALUE *vars = RANY(obj)->as.scope.local_vars-1; if (!(RANY(obj)->as.scope.flags & SCOPE_CLONE) && vars[0] == 0) @@ -1370,14 +1702,14 @@ obj_free(obj) break; case T_STRUCT: -if (RANY(obj)->as.rstruct.ptr) { RUBY_CRITICAL(free(RANY(obj)->as.rstruct.ptr)); -} -break; + if (RANY(obj)->as.rstruct.ptr) { + RUBY_CRITICAL(free(RANY(obj)->as.rstruct.ptr)); + } + break; default: -rb_bug("gc_sweep(): unknown data type 0x%lx(0x%lx)", RANY(obj)->as.basic.flags & T_MASK, obj); + rb_bug("gc_sweep(): unknown data type 0x%lx(0x%lx)", + RANY(obj)->as.basic.flags & T_MASK, obj); } return 0; @@ -1407,18 +1739,18 @@ _rb_setjmp:\n\ typedef unsigned long rb_jmp_buf[6]; __asm__ (".align 4\n\ _rb_setjmp:\n\ -pushl%ebp\n\ -movl%esp,%ebp\n\ -movl8(%ebp),%ebp\n\ -movl%eax,(%ebp)\n\ -movl%ebx,4(%ebp)\n\ -movl%ecx,8(%ebp)\n\ -movl%edx,12(%ebp)\n\ -movl%esi,16(%ebp)\n\ -movl%edi,20(%ebp)\n\ -popl%ebp\n\ -xorl%eax,%eax\n\ -ret"); + pushl %ebp\n\ + movl %esp,%ebp\n\ + movl 8(%ebp),%ebp\n\ + movl %eax,(%ebp)\n\ + movl %ebx,4(%ebp)\n\ + movl %ecx,8(%ebp)\n\ + movl %edx,12(%ebp)\n\ + movl %esi,16(%ebp)\n\ + movl %edi,20(%ebp)\n\ + popl %ebp\n\ + xorl %eax,%eax\n\ + ret"); #endif #endif int rb_setjmp (rb_jmp_buf); @@ -1431,41 +1763,50 @@ garbage_collect() struct gc_list *list; struct FRAME * volatile frame; /* gcc 2.7.2.3 -O2 bug?? jmp_buf save_regs_gc_mark; + struct timeval gctv1, gctv2; SET_STACK_END; */ #ifdef HAVE_NATIVETHREAD if (!is_ruby_native_thread()) { -rb_bug("cross-thread violation on rb_gc()"); + rb_bug("cross-thread violation on rb_gc()"); } #endif if (dont_gc || during_gc) { -if (!freelist) { add_heap(); -} -return; + if (!freelist) { + add_heap(); + } + return; } if (during_gc) return; during_gc++; + + + + + + + + if (gc_statistics) { gc_collections++; gettimeofday(&gctv1, NULL); if (verbose_gc_stats) { fprintf(gc_data_file, "Garbage collection started\n"); } } init_mark_stack(); gc_mark((VALUE)ruby_current_node, 0); /* mark frame stack */ for (frame = ruby_frame; frame; frame = frame->prev) { -rb_gc_mark_frame(frame); -if (frame->tmp) { struct FRAME *tmp = frame->tmp; while (tmp) { -rb_gc_mark_frame(tmp); -tmp = tmp->prev; } -} + rb_gc_mark_frame(frame); + if (frame->tmp) { + struct FRAME *tmp = frame->tmp; + while (tmp) { + rb_gc_mark_frame(tmp); + tmp = tmp->prev; + } + } } gc_mark((VALUE)ruby_scope, 0); gc_mark((VALUE)ruby_dyna_vars, 0); if (finalizer_table) { -mark_tbl(finalizer_table, 0); + mark_tbl(finalizer_table, 0); } FLUSH_REGISTER_WINDOWS; @@ -1478,9 +1819,9 @@ garbage_collect() rb_gc_mark_locations(rb_gc_stack_start, (VALUE*)STACK_END + 1); #else if ((VALUE*)STACK_END < rb_gc_stack_start) -rb_gc_mark_locations((VALUE*)STACK_END, rb_gc_stack_start); + rb_gc_mark_locations((VALUE*)STACK_END, rb_gc_stack_start); else -rb_gc_mark_locations(rb_gc_stack_start, (VALUE*)STACK_END + 1); + rb_gc_mark_locations(rb_gc_stack_start, (VALUE*)STACK_END + 1); #endif #ifdef __ia64 /* mark backing store (flushed register window on the stack) */ @@ -1489,13 +1830,13 @@ garbage_collect() #endif #if defined(__human68k__) || defined(__mc68000__) rb_gc_mark_locations((VALUE*)((char*)STACK_END + 2), - (VALUE*)((char*)rb_gc_stack_start + 2)); + (VALUE*)((char*)rb_gc_stack_start + 2)); #endif rb_gc_mark_threads(); /* mark protected global variables */ for (list = global_List; list; list = list->next) { -rb_gc_mark_maybe(*list->varptr); + rb_gc_mark_maybe(*list->varptr); } rb_mark_end_proc(); rb_gc_mark_global_tbl(); @@ -1510,18 +1851,30 @@ garbage_collect() /* gc_mark objects whose marking are not completed*/ do { -while (!MARK_STACK_EMPTY) { if (mark_stack_overflow){ -gc_mark_all(); } else { -gc_mark_rest(); } -} -rb_gc_abort_threads(); + while (!MARK_STACK_EMPTY) { + if (mark_stack_overflow){ + gc_mark_all(); + } + else { + gc_mark_rest(); + } + } + rb_gc_abort_threads(); } while (!MARK_STACK_EMPTY); gc_sweep(); + + + + + + + + + + + + if (gc_statistics) { GC_TIME_TYPE musecs_used; gettimeofday(&gctv2, NULL); musecs_used = ((GC_TIME_TYPE)(gctv2.tv_sec - gctv1.tv_sec) * 1000000) + (gctv2.tv_usec - gctv1.tv_usec); gc_time += musecs_used; if (verbose_gc_stats) { fprintf(gc_data_file, "GC time: %d msec\n", musecs_used / 1000); fflush(gc_data_file); } } } void @@ -1588,8 +1941,8 @@ Init_stack(addr) memset(&m, 0, sizeof(m)); VirtualQuery(&m, &m, sizeof(m)); rb_gc_stack_start = -STACK_UPPER((VALUE *)&m, (VALUE *)m.BaseAddress, (VALUE *)((char *)m.BaseAddress + m.RegionSize) - 1); + STACK_UPPER((VALUE *)&m, (VALUE *)m.BaseAddress, + (VALUE *)((char *)m.BaseAddress + m.RegionSize) - 1); #elif defined(STACK_END_ADDRESS) { extern void *STACK_END_ADDRESS; @@ -1599,24 +1952,24 @@ Init_stack(addr) if (!addr) addr = (void *)&addr; STACK_UPPER(&addr, addr, ++addr); if (rb_gc_stack_start) { -if (STACK_UPPER(&addr, -rb_gc_stack_start > addr, -rb_gc_stack_start < addr)) rb_gc_stack_start = addr; -return; + if (STACK_UPPER(&addr, + rb_gc_stack_start > addr, + rb_gc_stack_start < addr)) + rb_gc_stack_start = addr; + return; } rb_gc_stack_start = addr; #endif #ifdef HAVE_GETRLIMIT { -struct rlimit rlim; + struct rlimit rlim; -if (getrlimit(RLIMIT_STACK, &rlim) == 0) { unsigned int space = rlim.rlim_cur/5; + if (getrlimit(RLIMIT_STACK, &rlim) == 0) { + unsigned int space = rlim.rlim_cur/5; -} + + + if (space > 1024*1024) space = 1024*1024; STACK_LEVEL_MAX = (rlim.rlim_cur - space) / sizeof(VALUE); if (space > 1024*1024) space = 1024*1024; STACK_LEVEL_MAX = (rlim.rlim_cur - space) / sizeof(VALUE); } } #endif } @@ -1652,16 +2005,16 @@ void ruby_init_stack(VALUE *addr } #elif defined _WIN32 { -MEMORY_BASIC_INFORMATION mi; -DWORD size; -DWORD space; -if (VirtualQuery(&mi, &mi, sizeof(mi))) { size = (char *)mi.BaseAddress - (char *)mi.AllocationBase; space = size / 5; if (space > 1024*1024) space = 1024*1024; STACK_LEVEL_MAX = (size - space) / sizeof(VALUE); -} + MEMORY_BASIC_INFORMATION mi; + DWORD size; + + + + + + + + DWORD space; if (VirtualQuery(&mi, &mi, sizeof(mi))) { size = (char *)mi.BaseAddress - (char *)mi.AllocationBase; space = size / 5; if (space > 1024*1024) space = 1024*1024; STACK_LEVEL_MAX = (size - space) / sizeof(VALUE); } } #endif } @@ -1701,8 +2054,9 @@ void Init_heap() { if (!rb_gc_stack_start) { -Init_stack(0); + Init_stack(0); } + set_gc_parameters(); add_heap(); } @@ -1715,7 +2069,7 @@ os_obj_of(of) volatile VALUE v; for (i = 0; i < heaps_used; i++) { -RVALUE *p, *pend; + RVALUE *p, *pend; p = heaps[i].slot; pend = p + heaps[i].limit; for (;p < pend; p++) { @@ -1808,8 +2162,8 @@ add_final(os, block) { rb_warn("ObjectSpace::add_finalizer is deprecated; use define_finalizer"); if (!rb_respond_to(block, rb_intern("call"))) { -rb_raise(rb_eArgError, "wrong type argument %s (should be callable)", - rb_obj_classname(block)); + rb_raise(rb_eArgError, "wrong type argument %s (should be callable)", + rb_obj_classname(block)); } rb_ary_push(finalizers, block); return block; @@ -1864,7 +2218,7 @@ undefine_final(os, obj) VALUE os, obj; { if (finalizer_table) { -st_delete(finalizer_table, (st_data_t*)&obj, 0); + st_delete(finalizer_table, (st_data_t*)&obj, 0); } return obj; } @@ -1888,11 +2242,11 @@ define_final(argc, argv, os) rb_scan_args(argc, argv, "11", &obj, &block); if (argc == 1) { -block = rb_block_proc(); + block = rb_block_proc(); } else if (!rb_respond_to(block, rb_intern("call"))) { -rb_raise(rb_eArgError, "wrong type argument %s (should be callable)", - rb_obj_classname(block)); + rb_raise(rb_eArgError, "wrong type argument %s (should be callable)", + rb_obj_classname(block)); } need_call_final = 1; if (!FL_ABLE(obj)) { @@ -1905,10 +2259,10 @@ define_final(argc, argv, os) OBJ_FREEZE(block); if (!finalizer_table) { -finalizer_table = st_init_numtable(); + finalizer_table = st_init_numtable(); } if (st_lookup(finalizer_table, obj, &table)) { -rb_ary_push(table, block); + rb_ary_push(table, block); } else { table = rb_ary_new3(1, block); @@ -1927,7 +2281,7 @@ rb_gc_copy_finalizer(dest, obj) if (!finalizer_table) return; if (!FL_TEST(obj, FL_FINALIZE)) return; if (st_lookup(finalizer_table, obj, &table)) { -st_insert(finalizer_table, dest, table); + st_insert(finalizer_table, dest, table); } RBASIC(dest)->flags |= FL_FINALIZE; } @@ -1957,18 +2311,18 @@ run_final(obj) args[1] = 0; args[2] = (VALUE)ruby_safe_level; for (i=0; i<RARRAY(finalizers)->len; i++) { -args[0] = RARRAY(finalizers)->ptr[i]; -if (!args[1]) args[1] = rb_ary_new3(1, objid); -rb_protect((VALUE(*)_((VALUE)))run_single_final, (VALUE)args, &status); + + + args[0] = RARRAY(finalizers)->ptr[i]; if (!args[1]) args[1] = rb_ary_new3(1, objid); rb_protect((VALUE(*)_((VALUE)))run_single_final, (VALUE)args, &status); } if (finalizer_table && st_delete(finalizer_table, (st_data_t*)&obj, &table)) { -for (i=0; i<RARRAY(table)->len; i++) { VALUE final = RARRAY(table)->ptr[i]; args[0] = RARRAY(final)->ptr[1]; if (!args[1]) args[1] = rb_ary_new3(1, objid); args[2] = FIX2INT(RARRAY(final)->ptr[0]); rb_protect((VALUE(*)_((VALUE)))run_single_final, (VALUE)args, &status); -} + for (i=0; i<RARRAY(table)->len; i++) { + VALUE final = RARRAY(table)->ptr[i]; + args[0] = RARRAY(final)->ptr[1]; + if (!args[1]) args[1] = rb_ary_new3(1, objid); + args[2] = FIX2INT(RARRAY(final)->ptr[0]); + rb_protect((VALUE(*)_((VALUE)))run_single_final, (VALUE)args, &status); + } } rb_thread_critical = critical_save; } @@ -1980,8 +2334,8 @@ rb_gc_finalize_deferred() deferred_final_list = 0; if (p) { -finalize_list(p); -free_unused_heaps(); + finalize_list(p); + free_unused_heaps(); } } @@ -2061,7 +2415,7 @@ id2ref(obj, objid) if (ptr == Qfalse) return Qfalse; if (ptr == Qnil) return Qnil; if (FIXNUM_P(ptr)) return (VALUE)ptr; ptr = objid ^ FIXNUM_FLAG;/* unset FIXNUM_FLAG */ + ptr = objid ^ FIXNUM_FLAG; /* unset FIXNUM_FLAG */ if ((ptr % sizeof(RVALUE)) == (4 << 2)) { ID symid = ptr / sizeof(RVALUE); @@ -2075,7 +2429,7 @@ id2ref(obj, objid) rb_raise(rb_eRangeError, "0x%lx is not id value", p0); } if (BUILTIN_TYPE(ptr) == 0 || RBASIC(ptr)->klass == 0) { -rb_raise(rb_eRangeError, "0x%lx is recycled object", p0); + rb_raise(rb_eRangeError, "0x%lx is recycled object", p0); } return (VALUE)ptr; } @@ -2166,6 +2520,14 @@ Init_GC() rb_define_singleton_method(rb_mGC, "stress=", gc_stress_set, 1); rb_define_method(rb_mGC, "garbage_collect", rb_gc_start, 0); + + + + + + + + rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, "enable_stats", rb_gc_enable_stats, 0); "disable_stats", rb_gc_disable_stats, 0); "clear_stats", rb_gc_clear_stats, 0); "collections", rb_gc_collections, 0); "time", rb_gc_time, 0); "dump", rb_gc_dump, 0); "log", rb_gc_log, 1); rb_mObSpace = rb_define_module("ObjectSpace"); rb_define_module_function(rb_mObSpace, "each_object", os_each_obj, -1); rb_define_module_function(rb_mObSpace, "garbage_collect", rb_gc_start, 0); @@ -2188,7 +2550,7 @@ Init_GC() + rb_global_variable(&nomem_error); nomem_error = rb_exc_new3(rb_eNoMemError, rb_obj_freeze(rb_str_new2("failed to allocate memory"))); rb_obj_freeze(rb_str_new2("failed to allocate memory"))); OBJ_TAINT(nomem_error); OBJ_FREEZE(nomem_error); 1.26.5.1.11.1.12. 05-better-source-file-tracing.patch diff --git a/eval.c b/eval.c index fb3307c..356226e 100644 --- a/eval.c +++ b/eval.c @@ -1161,7 +1161,7 @@ static VALUE trace_func = 0; static int tracing = 0; static void call_trace_func _((rb_event_t,NODE*,VALUE,ID,VALUE)); -#if 0 +#if 1 #define SET_CURRENT_SOURCE() (ruby_sourcefile = ruby_current_node->nd_file, \ ruby_sourceline = nd_line(ruby_current_node)) #else 1.26.5.1.11.1.13. 16-caller-for-all-threads.patch diff --git a/eval.c b/eval.c index 356226e..a0fdc55 100644 --- a/eval.c +++ b/eval.c @@ -8199,6 +8199,17 @@ rb_f_method_name() } } +/* Hash (Thread => Backtrace) used to collect backtrace for each threads. */ +static VALUE backtrace_for_each_thread; + +static int backtrace_level_for_each_thread; + +static VALUE +switch_thread_context_to_collect_backtrace(rb_thread_t next); + +static VALUE +rb_f_caller_for_all_threads(); + void Init_eval() { @@ -8244,6 +8255,7 @@ Init_eval() rb_define_global_function("fail", rb_f_raise, -1); + rb_define_global_function("caller", rb_f_caller, -1); rb_define_global_function("caller_for_all_threads", rb_f_caller_for_all_threads, -1); rb_define_global_function("exit", rb_f_exit, -1); rb_define_global_function("abort", rb_f_abort, -1); @@ -10599,6 +10611,7 @@ static int th_sig, th_safe; #define RESTORE_RAISE5 #define RESTORE_SIGNAL6 #define RESTORE_EXIT7 +#define RESTORE_BACKTRACE8 extern VALUE *rb_gc_stack_start; #ifdef __ia64 @@ -10705,6 +10718,15 @@ rb_thread_switch(n) } rb_exc_raise(th_raise_exception); break; + case RESTORE_BACKTRACE: + rb_hash_aset(backtrace_for_each_thread, curr_thread->thread, + backtrace(backtrace_level_for_each_thread)); + if (curr_thread != main_thread) { + switch_thread_context_to_collect_backtrace(curr_thread->next); + } else { + /* Circled back to main thread, cycle is complete. */ + } + break; case RESTORE_NORMAL: default: break; @@ -13875,3 +13897,74 @@ rb_throw(tag, val) argv[1] = val; rb_f_throw(2, argv); } + +static VALUE +switch_thread_context_to_collect_backtrace(rb_thread_t next) +{ + if (THREAD_SAVE_CONTEXT(curr_thread)) { + return Qnil; + } + curr_thread = next; + rb_thread_restore_context(next, RESTORE_BACKTRACE); + return Qnil; +} + + +/* + * call-seq: + * caller_for_all_threads(start=1) => array + * + * Returns the current execution stack for all threads + * ---a hash whose keys are thread instances and values + * the thread caller backtrace. + * + * Backtraces are array of hashes indicating location on the + * stack. Hash keys include ``<em>:line</em>'' or ``<em>:file</em>'' + * and ``<em>:method'</em>''. + * + * The optional _start_ parameter + * determines the number of initial stack entries to omit from the + * result. + * + * def a(skip) + * caller_for_all_threads(skip) + * end + * def b(skip) + * a(skip) + * end + * def c(skip) + * b(skip) + * end + * c(0) #=> ["prog:2:in `a'", "prog:5:in `b'", "prog:8:in `c'", "prog:10"] + * c(1) #=> ["prog:5:in `b'", "prog:8:in `c'", "prog:11"] + * c(2) #=> ["prog:8:in `c'", "prog:12"] + * c(3) #=> ["prog:13"] + */ +static VALUE +rb_f_caller_for_all_threads(argc, argv) + int argc; + VALUE *argv; +{ + volatile int critical; + VALUE level; +VALUE result; + + rb_scan_args(argc, argv, "01", &level); + backtrace_level_for_each_thread = NIL_P(level) ? 0 : NUM2INT(level); +if (backtrace_level_for_each_thread < 0) { +rb_raise(rb_eArgError, "negative level (%d)", backtrace_level_for_each_thread); +} + +critical = rb_thread_critical; +rb_thread_critical = Qtrue; + + backtrace_for_each_thread = rb_hash_new(); + switch_thread_context_to_collect_backtrace(main_thread->next); + +result = backtrace_for_each_thread; +backtrace_for_each_thread = Qnil; +backtrace_for_each_thread = 0; + +rb_thread_critical = critical; + return result; +} diff --git a/test/callerforallthreads/test_caller_for_each_thread.rb b/test/callerforallthreads/test_caller_for_each_thread.rb new file mode 100644 index 0000000..6aebaed --- /dev/null +++ b/test/callerforallthreads/test_caller_for_each_thread.rb @@ -0,0 +1,95 @@ +# -*- ruby-indent-level: 4 -*+require 'thread' +require 'test/unit' + +class AClassWithNestedmethods + + def an_ultra_nested_method(skip) + caller_for_all_threads skip + end + + def a_nested_method(skip) + an_ultra_nested_method skip + end + + def a_method(skip=0) + a_nested_method skip + end + +end + +class CallerForEachThreadTest < Test::Unit::TestCase + + def testCollectMeaningfulBacktraceForASingleThread + backtraces = AClassWithNestedmethods.new.a_method + backtrace = backtraces[Thread.current] + assert_not_nil backtrace + assert_equal __FILE__ + ":8:in `an_ultra_nested_method'", backtrace[0] + assert_equal __FILE__ + ":12:in `a_nested_method'", backtrace[1] + assert_equal __FILE__ + ":16:in `a_method'", backtrace[2] + assert_equal __FILE__ + ":24:in `testCollectMeaningfulBacktraceForASingleThread'", + backtrace[3] + end + + def testCanSkipFirstStackEntries + backtraces = AClassWithNestedmethods.new.a_method 2 + backtrace = backtraces[Thread.current] + assert_not_nil backtrace + assert_equal __FILE__ + ":16:in `a_method'", backtrace[0] + assert_equal __FILE__ + ":35:in `testCanSkipFirstStackEntries'", + backtrace[1] + end + + def testCollectMeaningfulBacktraceForMultipleThreads + first_thread = Thread.new do + loop do + Thread.pass + sleep 1 + end + end + + second_thread = Thread.new do + loop do + Thread.pass + sleep 1 + end + end + + backtraces = AClassWithNestedmethods.new.a_method + + backtrace = backtraces[Thread.current] + assert_not_nil backtrace + assert_match __FILE__ + ":8:in `an_ultra_nested_method'", backtrace[0] + assert_match __FILE__ + ":12:in `a_nested_method'", backtrace[1] + assert_equal __FILE__ + ":16:in `a_method'", backtrace[2] + assert_equal __FILE__ + ":58:in `testCollectMeaningfulBacktraceForMultipleThreads'", + backtrace[3] + + backtrace = backtraces[first_thread] + assert_not_nil backtrace + assert_equal __FILE__ + ":47:in `testCollectMeaningfulBacktraceForMultipleThreads'", + backtrace[0] + assert_equal __FILE__ + ":45:in `loop'", + backtrace[1] + assert_equal __FILE__ + ":45:in `testCollectMeaningfulBacktraceForMultipleThreads'", + backtrace[2] + assert_equal __FILE__ + ":44:in `initialize'",backtrace[3] + assert_equal __FILE__ + ":44:in `new'", backtrace[4] + assert_equal __FILE__ + ":44:in `testCollectMeaningfulBacktraceForMultipleThreads'", + backtrace[5] + + backtrace = backtraces[second_thread] + assert_not_nil backtrace + assert_equal __FILE__ + ":53:in `testCollectMeaningfulBacktraceForMultipleThreads'", + backtrace[0] + assert_equal __FILE__ + ":52:in `loop'", backtrace[1] + assert_equal __FILE__ + ":52:in `testCollectMeaningfulBacktraceForMultipleThreads'", + backtrace[2] + assert_equal __FILE__ + ":51:in `initialize'",backtrace[3] + assert_equal __FILE__ + ":51:in `new'", backtrace[4] + assert_equal __FILE__ + ":51:in `testCollectMeaningfulBacktraceForMultipleThreads'", + backtrace[5] + end + +end + 1.26.5.1.11.1.14. 09-track-object-allocation.patch diff --git a/gc.c b/gc.c index 30a1219..5b42b90 100644 --- a/gc.c +++ b/gc.c @@ -96,6 +96,26 @@ static void garbage_collect(); int ruby_gc_stress = 0; +static unsigned long live_objects = 0; +unsigned long rb_os_live_objects() +{ + return live_objects; +} + +#if defined(HAVE_LONG_LONG) +static unsigned LONG_LONG allocated_objects = 0; +unsigned LONG_LONG rb_os_allocated_objects() +{ + return allocated_objects; +} +#else +static unsigned long allocated_objects = 0; +unsigned long rb_os_allocated_objects() +{ + return allocated_objects; +} +#endif + NORETURN(void rb_exc_jump _((VALUE))); void @@ -987,6 +1007,8 @@ rb_newobj() RANY(obj)->file = ruby_sourcefile; RANY(obj)->line = ruby_sourceline; #endif + live_objects++; + allocated_objects++; return obj; } @@ -1825,6 +1847,7 @@ gc_sweep() add_heap(); } during_gc = 0; + live_objects = live; if (do_gc_stats) { fprintf(gc_data_file, "objects processed: %.7d\n", live+freed); @@ -2790,6 +2813,35 @@ rb_obj_id(VALUE obj) return (VALUE)((long)obj|FIXNUM_FLAG); } +/* call-seq: + * ObjectSpace.live_objects => number + * + * Returns the count of objects currently allocated in the system. This goes + * down after the garbage collector runs. + */ +static +VALUE os_live_objects(VALUE self) +{ + return ULONG2NUM(live_objects); +} + +/* call-seq: + * ObjectSpace.allocated_objects => number + * + * Returns the count of objects allocated since the Ruby interpreter has + * started. This number can only increase. To know how many objects are + * currently allocated, use ObjectSpace::live_objects + */ +static +VALUE os_allocated_objects(VALUE self) +{ +#if defined(HAVE_LONG_LONG) + return ULL2NUM(allocated_objects); +#else + return ULONG2NUM(allocated_objects); +#endif +} + /* * The <code>GC</code> module provides an interface to Ruby's mark and * sweep garbage collection mechanism. Some of the underlying methods @@ -2833,6 +2885,9 @@ Init_GC() rb_define_module_function(rb_mObSpace, "finalizers", finals, 0); rb_define_module_function(rb_mObSpace, "call_finalizer", call_final, 1); + + + rb_define_module_function(rb_mObSpace, "live_objects", os_live_objects, 0); rb_define_module_function(rb_mObSpace, "allocated_objects", os_allocated_objects, 0); rb_define_module_function(rb_mObSpace, "define_finalizer", define_final, -1); rb_define_module_function(rb_mObSpace, "undefine_finalizer", undefine_final, 1); diff --git a/intern.h b/intern.h index 1117614..a87661d 100644 --- a/intern.h +++ b/intern.h @@ -274,6 +274,12 @@ void rb_gc_before_fork _((void)); void rb_gc_after_fork _((void)); VALUE rb_gc_allocated_size _((void)); VALUE rb_gc_num_allocations _((void)); +unsigned long rb_os_live_objects _((void)); +#ifdef HAVE_LONG_LONG +unsigned LONG_LONG rb_os_allocated_objects _((void)); +#else +unsigned long rb_os_allocated_objects _((void)); +#endif /* hash.c */ void st_foreach_safe _((struct st_table *, int (*)(ANYARGS), unsigned long)); void rb_hash_foreach _((VALUE, int (*)(ANYARGS), VALUE)); 1.26.5.1.11.1.15. 02-sigvtalrm-fix.patch diff --git a/eval.c b/eval.c index 7886e17..6ff2560 100644 --- a/eval.c +++ b/eval.c @@ -12461,6 +12461,11 @@ rb_thread_start_0(fn, arg, th) curr_thread->next = th; th->priority = curr_thread->priority; th->thgroup = curr_thread->thgroup; +#if defined(HAVE_SETITIMER) || defined(_THREAD_SAFE) + if (!thread_init) { + rb_thread_start_timer(); + } +#endif } START_TIMER(); @@ -13189,7 +13194,9 @@ rb_thread_atfork() main_thread = curr_thread; curr_thread->next = curr_thread; curr_thread->prev = curr_thread; STOP_TIMER(); +#if defined(HAVE_SETITIMER) || defined(_THREAD_SAFE) + rb_thread_stop_timer(); +#endif } 1.26.5.1.11.1.16. 10-expose-heap-slots.patch diff --git a/gc.c b/gc.c index 5b42b90..21b3f6b 100644 --- a/gc.c +++ b/gc.c @@ -690,6 +690,7 @@ static int heaps_used = 0; static int heap_min_slots = 10000; static int heap_slots = 10000; +static int heap_size = 0; static int heap_free_min = 4096; static int heap_slots_increment = 10000; @@ -800,6 +801,21 @@ static void set_gc_parameters() /* * call-seq: + * GC.heap_slots => Integer + * + * Returns the number of heap slots available for object allocations. + * + * GC.heap_slots #=> 10000 + * + */ +VALUE +rb_gc_heap_slots() +{ + return INT2NUM(heap_size); +} + +/* + * call-seq: * GC.dump => nil * * dumps information about the current GC data structures to the GC log file @@ -967,6 +983,7 @@ add_heap() heaps[heaps_used].limit = heap_slots; break; } + heap_size += heap_slots; pend = p + heap_slots; if (lomem == 0 || lomem > p) lomem = p; if (himem < pend) himem = pend; @@ -1828,6 +1845,7 @@ gc_sweep() if (n == heaps[i].limit && freed > free_min) { RVALUE *pp; + heap_size -= n; heaps[i].limit = 0; for (pp = final_list; pp != final; pp = pp->as.free.next) { pp->as.free.flags |= FL_SINGLETON; /* freeing page mark */ @@ -2866,6 +2884,7 @@ Init_GC() rb_define_singleton_method(rb_mGC, "clear_stats", rb_gc_clear_stats, 0); rb_define_singleton_method(rb_mGC, "allocated_size", rb_gc_allocated_size, 0); rb_define_singleton_method(rb_mGC, "num_allocations", rb_gc_num_allocations, 0); + rb_define_singleton_method(rb_mGC, "heap_slots", rb_gc_heap_slots, 0); rb_define_singleton_method(rb_mGC, "collections", rb_gc_collections, 0); rb_define_singleton_method(rb_mGC, "time", rb_gc_time, 0); rb_define_singleton_method(rb_mGC, "dump", rb_gc_dump, 0); diff --git a/intern.h b/intern.h index a87661d..e8f3209 100644 --- a/intern.h +++ b/intern.h @@ -274,6 +274,7 @@ void rb_gc_before_fork _((void)); void rb_gc_after_fork _((void)); VALUE rb_gc_allocated_size _((void)); VALUE rb_gc_num_allocations _((void)); +VALUE rb_gc_heap_slots _((void)); unsigned long rb_os_live_objects _((void)); #ifdef HAVE_LONG_LONG unsigned LONG_LONG rb_os_allocated_objects _((void)); 1.26.5.1.12. p334 1.26.5.1.12.1. railsexpress 1.26.5.1.12.1.1. 09-track-malloc-size.patch diff --git a/gc.c b/gc.c index a3cbe91..30a1219 100644 --- a/gc.c +++ b/gc.c @@ -79,6 +79,17 @@ void *alloca (); static unsigned long malloc_increase = 0; static unsigned long malloc_limit = GC_MALLOC_LIMIT; + +#ifdef HAVE_LONG_LONG +static unsigned LONG_LONG gc_allocated_size = 0; +static unsigned LONG_LONG gc_num_allocations = 0; +#else +static unsigned long gc_allocated_size = 0; +static unsigned long gc_num_allocations = 0; +#endif +static int gc_statistics = 0; + + static void run_final(); static VALUE nomem_error; static void garbage_collect(); @@ -163,6 +174,11 @@ ruby_xmalloc(size) } malloc_increase += size; + if (gc_statistics) { + gc_allocated_size += size; +gc_num_allocations += 1; + } + return mem; } @@ -220,7 +236,6 @@ ruby_xfree(x) extern int ruby_in_compile; static int dont_gc; -static int gc_statistics = 0; static GC_TIME_TYPE gc_time = 0; static int gc_collections = 0; static int verbose_gc_stats = Qfalse; @@ -329,11 +344,55 @@ rb_gc_clear_stats() { gc_collections = 0; gc_time = 0; + gc_allocated_size = 0; + gc_num_allocations = 0; return Qnil; } /* * call-seq: + * GC.allocated_size => Integer + * + * Returns the size of memory (in bytes) allocated since GC statistics collection + * was enabled. + * + * GC.allocated_size #=> 35 + * + */ +VALUE +rb_gc_allocated_size() +{ +#if HAVE_LONG_LONG + return ULL2NUM(gc_allocated_size); +#else + return ULONG2NUM(gc_allocated_size); +#endif +} + +/* + * call-seq: + * GC.num_allocations => Integer + * + * Returns the number of memory allocations since GC statistics collection + * was enabled. + * + * GC.num_allocations #=> 150 + * + */ +VALUE +rb_gc_num_allocations() +{ +#if HAVE_LONG_LONG + return ULL2NUM(gc_num_allocations); +#else + return ULONG2NUM(gc_num_allocations); +#endif +} + +/* + +/* + * call-seq: * GC.collections => Integer * * Returns the number of garbage collections performed while GC statistics collection @@ -2753,6 +2812,8 @@ Init_GC() rb_define_singleton_method(rb_mGC, "enable_stats", rb_gc_enable_stats, 0); rb_define_singleton_method(rb_mGC, "disable_stats", rb_gc_disable_stats, 0); rb_define_singleton_method(rb_mGC, "clear_stats", rb_gc_clear_stats, 0); + rb_define_singleton_method(rb_mGC, "allocated_size", rb_gc_allocated_size, 0); + rb_define_singleton_method(rb_mGC, "num_allocations", rb_gc_num_allocations, 0); rb_define_singleton_method(rb_mGC, "collections", rb_gc_collections, 0); rb_define_singleton_method(rb_mGC, "time", rb_gc_time, 0); rb_define_singleton_method(rb_mGC, "dump", rb_gc_dump, 0); diff --git a/intern.h b/intern.h index 49e1827..78bf699 100644 --- a/intern.h +++ b/intern.h @@ -272,6 +272,8 @@ VALUE rb_gc_disable _((void)); VALUE rb_gc_start _((void)); void rb_gc_before_fork _((void)); void rb_gc_after_fork _((void)); +VALUE rb_gc_allocated_size _((void)); +VALUE rb_gc_num_allocations _((void)); /* hash.c */ void st_foreach_safe _((struct st_table *, int (*)(ANYARGS), unsigned long)); void rb_hash_foreach _((VALUE, int (*)(ANYARGS), VALUE)); 1.26.5.1.12.1.2. 16-add-object-size-information-to-heap-dump.patch diff --git a/gc.c b/gc.c index 0ce7e68..53450bf 100644 --- a/gc.c +++ b/gc.c @@ -953,9 +953,21 @@ rb_gc_dump_file_and_line_info(int argc, VALUE *argv) if (!p->as.basic.klass) { fprintf(f, "__unknown__"); } else { fprintf(f, rb_obj_classname((VALUE)p)); + fprintf(f, "%s", rb_obj_classname((VALUE)p)); } } + /* print object size for some known object types */ + switch (TYPE(p)) { + case T_STRING: + fprintf(f, ":%lu", RSTRING(p)->len); + break; + case T_ARRAY: + fprintf(f, ":%lu", RARRAY(p)->len); + break; + case T_HASH: + fprintf(f, ":%d", RHASH(p)->tbl->num_entries); + break; + } } fprintf(f, "\n"); } @@ -1924,10 +1936,10 @@ gc_sweep() heap_slots_live_after_last_gc = live; if (do_gc_stats) { fprintf(gc_data_file, "objects processed: %.7d\n", live+freed); fprintf(gc_data_file, "live objects : %.7d\n", live); fprintf(gc_data_file, "freelist objects : %.7d\n", freed - really_freed); fprintf(gc_data_file, "freed objects : %.7d\n", really_freed); fprintf(gc_data_file, "objects processed: %.7lu\n", live+freed); fprintf(gc_data_file, "live objects : %.7lu\n", live); fprintf(gc_data_file, "freelist objects : %.7lu\n", freed - really_freed); fprintf(gc_data_file, "freed objects : %.7lu\n", really_freed); for(i=0; i<256; i++) { if (free_counts[i]>0 || live_counts[i]>0) { fprintf(gc_data_file, @@ -2258,7 +2270,7 @@ garbage_collect() gc_time += musecs_used; + + + + if (verbose_gc_stats) { fprintf(gc_data_file, "GC time: %d msec\n", musecs_used / 1000); fprintf(gc_data_file, "GC time: %ld msec\n", (long)(musecs_used / 1000)); fflush(gc_data_file); } + } 1.26.5.1.12.1.3. 15-track-live-dataset-size.patch diff --git a/gc.c b/gc.c index 2c34932..0ce7e68 100644 --- a/gc.c +++ b/gc.c @@ -89,6 +89,7 @@ static unsigned long gc_num_allocations = 0; #endif static int gc_statistics = 0; +static unsigned long heap_slots_live_after_last_gc = 0; static void run_final(); static VALUE nomem_error; @@ -465,6 +466,23 @@ rb_gc_time() #endif } +/* + * call-seq: + * GC.heap_slots_live_after_last_gc => Integer + * + * Returns the number of heap slots which were live after the last garbage collection. + * + * GC.heap_slots_live_after_last_gc #=> 231223 + * + */ +VALUE +rb_gc_heap_slots_live_after_last_gc() +{ + return ULONG2NUM(heap_slots_live_after_last_gc); +} + + + VALUE rb_mGC; /* @@ -1903,6 +1921,7 @@ gc_sweep() } during_gc = 0; live_objects = live; + heap_slots_live_after_last_gc = live; if (do_gc_stats) { fprintf(gc_data_file, "objects processed: %.7d\n", live+freed); @@ -2924,6 +2943,7 @@ Init_GC() rb_define_singleton_method(rb_mGC, "allocated_size", rb_gc_allocated_size, 0); rb_define_singleton_method(rb_mGC, "num_allocations", rb_gc_num_allocations, 0); rb_define_singleton_method(rb_mGC, "heap_slots", rb_gc_heap_slots, 0); + rb_define_singleton_method(rb_mGC, "heap_slots_live_after_last_gc", rb_gc_heap_slots_live_after_last_gc, 0); rb_define_const(rb_mGC, "HEAP_SLOT_SIZE", INT2FIX(sizeof(RVALUE))); rb_define_singleton_method(rb_mGC, "collections", rb_gc_collections, 0); rb_define_singleton_method(rb_mGC, "time", rb_gc_time, 0); 1.26.5.1.12.1.4. 14-add-trace-stats-enabled-methods.patch diff --git a/gc.c b/gc.c index 57740d2..2c34932 100644 --- a/gc.c +++ b/gc.c @@ -350,6 +350,22 @@ rb_gc_disable_stats() /* * call-seq: + * GC.stats_enabled? => true or false + * + * Check whether GC stats have been enabled. + * + * GC.stats_enabled? #=> false or true + * + */ + +VALUE +rb_gc_stats_enabled() +{ + return gc_statistics ? Qtrue : Qfalse; +} + +/* + * call-seq: * GC.clear_stats => nil * * Clears garbage collection statistics, returning nil. This resets the number @@ -491,6 +507,22 @@ rb_gc_disable_trace() return old; } +/* + * call-seq: + * GC.trace_enabled? => true or false + * + * Check whether GC tracing has been enabled. + * + * GC.trace_enabled? #=> false or true + * + */ + +VALUE +rb_gc_trace_enabled() +{ + return verbose_gc_stats ? Qtrue : Qfalse; +} + char* GC_LOGFILE_IVAR = "@gc_logfile_name"; /* @@ -2887,6 +2919,7 @@ Init_GC() rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, + rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, @@ -2902,6 +2935,7 @@ Init_GC() rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, + rb_define_singleton_method(rb_mGC, "enable_stats", rb_gc_enable_stats, 0); "disable_stats", rb_gc_disable_stats, 0); "stats_enabled?", rb_gc_stats_enabled, 0); "clear_stats", rb_gc_clear_stats, 0); "allocated_size", rb_gc_allocated_size, 0); "num_allocations", rb_gc_num_allocations, 0); "log_file", rb_gc_log_file, -1); "enable_trace", rb_gc_enable_trace, 0); "disable_trace", rb_gc_disable_trace, 0); "trace_enabled?", rb_gc_trace_enabled, 0); rb_mObSpace = rb_define_module("ObjectSpace"); rb_define_module_function(rb_mObSpace, "each_object", os_each_obj, -1); 1.26.5.1.12.1.5. 10-track-object-allocation.patch diff --git a/gc.c b/gc.c index 30a1219..5b42b90 100644 --- a/gc.c +++ b/gc.c @@ -96,6 +96,26 @@ static void garbage_collect(); int ruby_gc_stress = 0; +static unsigned long live_objects = 0; +unsigned long rb_os_live_objects() +{ + return live_objects; +} + +#if defined(HAVE_LONG_LONG) +static unsigned LONG_LONG allocated_objects = 0; +unsigned LONG_LONG rb_os_allocated_objects() +{ + return allocated_objects; +} +#else +static unsigned long allocated_objects = 0; +unsigned long rb_os_allocated_objects() +{ + return allocated_objects; +} +#endif + NORETURN(void rb_exc_jump _((VALUE))); void @@ -987,6 +1007,8 @@ rb_newobj() RANY(obj)->file = ruby_sourcefile; RANY(obj)->line = ruby_sourceline; #endif + live_objects++; + allocated_objects++; return obj; } @@ -1825,6 +1847,7 @@ gc_sweep() add_heap(); } during_gc = 0; + live_objects = live; if (do_gc_stats) { fprintf(gc_data_file, "objects processed: %.7d\n", live+freed); @@ -2790,6 +2813,35 @@ rb_obj_id(VALUE obj) return (VALUE)((long)obj|FIXNUM_FLAG); } +/* call-seq: + * ObjectSpace.live_objects => number + * + * Returns the count of objects currently allocated in the system. This goes + * down after the garbage collector runs. + */ +static +VALUE os_live_objects(VALUE self) +{ + return ULONG2NUM(live_objects); +} + +/* call-seq: + * ObjectSpace.allocated_objects => number + * + * Returns the count of objects allocated since the Ruby interpreter has + * started. This number can only increase. To know how many objects are + * currently allocated, use ObjectSpace::live_objects + */ +static +VALUE os_allocated_objects(VALUE self) +{ +#if defined(HAVE_LONG_LONG) + return ULL2NUM(allocated_objects); +#else + return ULONG2NUM(allocated_objects); +#endif +} + /* * The <code>GC</code> module provides an interface to Ruby's mark and * sweep garbage collection mechanism. Some of the underlying methods @@ -2833,6 +2885,9 @@ Init_GC() rb_define_module_function(rb_mObSpace, "finalizers", finals, 0); rb_define_module_function(rb_mObSpace, "call_finalizer", call_final, 1); + + + rb_define_module_function(rb_mObSpace, "live_objects", os_live_objects, 0); rb_define_module_function(rb_mObSpace, "allocated_objects", os_allocated_objects, 0); rb_define_module_function(rb_mObSpace, "define_finalizer", define_final, -1); rb_define_module_function(rb_mObSpace, "undefine_finalizer", undefine_final, 1); diff --git a/intern.h b/intern.h index 78bf699..86b4395 100644 --- a/intern.h +++ b/intern.h @@ -274,6 +274,12 @@ void rb_gc_before_fork _((void)); void rb_gc_after_fork _((void)); VALUE rb_gc_allocated_size _((void)); VALUE rb_gc_num_allocations _((void)); +unsigned long rb_os_live_objects _((void)); +#ifdef HAVE_LONG_LONG +unsigned LONG_LONG rb_os_allocated_objects _((void)); +#else +unsigned long rb_os_allocated_objects _((void)); +#endif /* hash.c */ void st_foreach_safe _((struct st_table *, int (*)(ANYARGS), unsigned long)); void rb_hash_foreach _((VALUE, int (*)(ANYARGS), VALUE)); 1.26.5.1.12.1.6. 12-fix-heap-size-growth-logic.patch diff --git a/gc.c b/gc.c index 21b3f6b..7db1ef6 100644 --- a/gc.c +++ b/gc.c @@ -694,6 +694,7 @@ static int heap_size = 0; static static +static static int heap_free_min = 4096; int heap_slots_increment = 10000; int initial_heap_slots_increment = 10000; double heap_slots_growth_factor = 1.8; static long initial_malloc_limit = GC_MALLOC_LIMIT; @@ -771,14 +772,13 @@ static void set_gc_parameters() if (verbose_gc_stats) { fprintf(gc_data_file, "RUBY_HEAP_SLOTS_INCREMENT=%s\n", heap_slots_incr_ptr); } if (heap_slots_incr_i > 0) { heap_slots_increment = heap_slots_incr_i; } + heap_slots_increment = heap_slots_incr_i; + initial_heap_slots_increment = heap_slots_increment; } heap_slots_growth_factor_ptr = getenv("RUBY_HEAP_SLOTS_GROWTH_FACTOR"); if (heap_slots_growth_factor_ptr != NULL) { double heap_slots_growth_factor_d = atoi(heap_slots_growth_factor_ptr); + double heap_slots_growth_factor_d = atof(heap_slots_growth_factor_ptr); if (verbose_gc_stats) { fprintf(gc_data_file, "RUBY_HEAP_SLOTS_GROWTH_FACTOR=%s\n", heap_slots_growth_factor_ptr); } @@ -988,8 +988,13 @@ add_heap() if (lomem == 0 || lomem > p) lomem = p; if (himem < pend) himem = pend; heaps_used++; heap_slots += heap_slots_increment; heap_slots_increment *= heap_slots_growth_factor; + if (heaps_used == 1) + heap_slots = initial_heap_slots_increment; + else { + heap_slots_increment *= heap_slots_growth_factor; + heap_slots += heap_slots_increment; + } + if (heap_slots <= 0) heap_slots = heap_min_slots; while (p < pend) { @@ -1879,6 +1884,7 @@ gc_sweep() live_counts[i], free_counts[i], obj_type(i)); } } + rb_gc_dump(); fflush(gc_data_file); } 1.26.5.1.12.1.7. 02-fix-rcs-keyword-idiom.patch diff --git a/lib/logger.rb b/lib/logger.rb index 15d95fc..69f0d7b 100644 --- a/lib/logger.rb +++ b/lib/logger.rb @@ -171,7 +171,13 @@ require 'monitor' class Logger VERSION = "1.2.6" id, name, rev = %w$Id$ - ProgName = "#{name.chomp(",v")}/#{rev}" + if name + name = name.chomp(",v") + else + name = File.basename(__FILE__) + end + rev ||= "v#{VERSION}" + ProgName = "#{name}/#{rev}" class Error < RuntimeError; end class ShiftingError < Error; end 1.26.5.1.12.1.8. 01-ignore-generated-files.patch diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..00c347a --- /dev/null +++ b/.gitignore @@ -0,0 +1,95 @@ +.ext +.installed.list +.rbconfig.time +Makefile +autom4te.cache/ +config.h +config.status +configure +ext/Win32API/Makefile +ext/bigdecimal/Makefile +ext/curses/Makefile +ext/dbm/Makefile +ext/digest/Makefile +ext/digest/bubblebabble/Makefile +ext/digest/md5/Makefile +ext/digest/rmd160/Makefile +ext/digest/sha1/Makefile +ext/digest/sha2/Makefile +ext/dl/Makefile +ext/dl/call.func +ext/dl/callback.func +ext/dl/cbtable.func +ext/dl/dlconfig.h +ext/dl/dlconfig.rb +ext/enumerator/Makefile +ext/etc/Makefile +ext/fcntl/Makefile +ext/gdbm/Makefile +ext/iconv/Makefile +ext/io/wait/Makefile +ext/nkf/Makefile +ext/openssl/Makefile +ext/openssl/extconf.h +ext/pty/Makefile +ext/racc/cparse/Makefile +ext/readline/Makefile +ext/sdbm/Makefile +ext/socket/Makefile +ext/stringio/Makefile +ext/strscan/Makefile +ext/syck/Makefile +ext/syslog/Makefile +ext/thread/Makefile +ext/tk/Makefile +ext/tk/tkutil/Makefile +ext/win32ole/Makefile +ext/win32ole/.document +ext/zlib/Makefile +largefile.h +miniruby +parse.c +rbconfig.rb +ruby +enc.mk +ext/bigdecimal/extconf.h +ext/continuation/ +ext/coverage/ +ext/curses/extconf.h +ext/dbm/extconf.h +ext/digest/bubblebabble/extconf.h +ext/digest/extconf.h +ext/digest/md5/extconf.h +ext/digest/rmd160/extconf.h +ext/digest/sha1/extconf.h +ext/digest/sha2/extconf.h +ext/dl/callback.h +ext/dl/extconf.h +ext/etc/extconf.h +ext/fcntl/extconf.h +ext/fiber/ +ext/iconv/extconf.h +ext/io/wait/extconf.h +ext/json/ +ext/nkf/extconf.h +ext/pty/extconf.h +ext/racc/cparse/extconf.h +ext/readline/extconf.h +ext/ripper/ +ext/sdbm/extconf.h +ext/socket/constants.h +ext/socket/extconf.h +ext/stringio/extconf.h +ext/strscan/extconf.h +ext/syck/extconf.h +ext/syslog/extconf.h +ext/tk/extconf.h +ext/tk/tkutil/extconf.h +ext/zlib/extconf.h +miniprelude.c +prelude.c +revision.h +*.dylib +*.log +*.dSYM +patches-ruby* 1.26.5.1.12.1.9. 04-railsbench-gc-patch.patch diff --git a/gc.c b/gc.c index fa45cd1..ab71d22 100644 --- a/gc.c +++ b/gc.c @@ -22,8 +22,16 @@ #include <setjmp.h> #include <sys/types.h> +#ifdef _WIN32 +#include <string.h> +#else +#include <strings.h> +#endif + #ifdef HAVE_SYS_TIME_H #include <sys/time.h> +#elif defined(_WIN32) +#include <time.h> #endif #ifdef HAVE_SYS_RESOURCE_H @@ -42,7 +50,6 @@ void rb_io_fptr_finalize _((struct rb_io_t*)); #ifdef __CYGWIN__ int _setjmp(), _longjmp(); #endif /* Make alloca work the best possible way. */ #ifdef __GNUC__ # ifndef atarist @@ -86,12 +93,12 @@ rb_memerror() rb_thread_t th = rb_curr_thread; if (!nomem_error || -(rb_thread_raised_p(th, RAISED_NOMEMORY) && rb_safe_level() < 4)) { -fprintf(stderr, "[FATAL] failed to allocate memory\n"); -exit(1); + (rb_thread_raised_p(th, RAISED_NOMEMORY) && rb_safe_level() < 4)) { + fprintf(stderr, "[FATAL] failed to allocate memory\n"); + exit(1); } if (rb_thread_raised_p(th, RAISED_NOMEMORY)) { -rb_exc_jump(nomem_error); + rb_exc_jump(nomem_error); } rb_thread_raised_set(th, RAISED_NOMEMORY); rb_exc_raise(nomem_error); @@ -139,7 +146,7 @@ ruby_xmalloc(size) void *mem; if (size < 0) { -rb_raise(rb_eNoMemError, "negative allocation size (or too big)"); + rb_raise(rb_eNoMemError, "negative allocation size (or too big)"); } if (size == 0) size = 1; @@ -148,11 +155,11 @@ ruby_xmalloc(size) } RUBY_CRITICAL(mem = malloc(size)); if (!mem) { -garbage_collect(); -RUBY_CRITICAL(mem = malloc(size)); -if (!mem) { rb_memerror(); -} + garbage_collect(); + RUBY_CRITICAL(mem = malloc(size)); + if (!mem) { + rb_memerror(); + } } malloc_increase += size; @@ -179,17 +186,17 @@ ruby_xrealloc(ptr, size) void *mem; if (size < 0) { -rb_raise(rb_eArgError, "negative re-allocation size"); + rb_raise(rb_eArgError, "negative re-allocation size"); } if (!ptr) return xmalloc(size); if (size == 0) size = 1; if (ruby_gc_stress) garbage_collect(); RUBY_CRITICAL(mem = realloc(ptr, size)); if (!mem) { -garbage_collect(); -RUBY_CRITICAL(mem = realloc(ptr, size)); -if (!mem) { rb_memerror(); + garbage_collect(); + RUBY_CRITICAL(mem = realloc(ptr, size)); + if (!mem) { + rb_memerror(); } } malloc_increase += size; @@ -202,11 +209,20 @@ ruby_xfree(x) void *x; { if (x) -RUBY_CRITICAL(free(x)); + RUBY_CRITICAL(free(x)); } +#if HAVE_LONG_LONG +#define GC_TIME_TYPE LONG_LONG +#else +#define GC_TIME_TYPE long +#endif + extern int ruby_in_compile; static int dont_gc; +static int gc_statistics = 0; +static GC_TIME_TYPE gc_time = 0; +static int gc_collections = 0; static int during_gc; static int need_call_final = 0; static st_table *finalizer_table = 0; @@ -241,7 +257,7 @@ rb_gc_enable() * Disables garbage collection, returning <code>true</code> if garbage * collection was already disabled. * - * GC.disable #=> false + * GC.disable #=> false or true * GC.disable #=> true * */ @@ -255,6 +271,104 @@ rb_gc_disable() return old; } +/* + * call-seq: + * GC.enable_stats => true or false + * + * Enables garbage collection statistics, returning <code>true</code> if garbage + * collection statistics was already enabled. + * + * GC.enable_stats #=> false or true + * GC.enable_stats #=> true + * + */ + +VALUE +rb_gc_enable_stats() +{ + int old = gc_statistics; + gc_statistics = Qtrue; + return old; +} + +/* + * call-seq: + * GC.disable_stats => true or false + * + * Disables garbage collection statistics, returning <code>true</code> if garbage + * collection statistics was already disabled. + * + * GC.disable_stats #=> false or true + * GC.disable_stats #=> true + * + */ + +VALUE +rb_gc_disable_stats() +{ + int old = gc_statistics; + gc_statistics = Qfalse; + return old; +} + +/* + * call-seq: + * GC.clear_stats => nil + * + * Clears garbage collection statistics, returning nil. This resets the number + * of collections (GC.collections) and the time used (GC.time) to 0. + * + * GC.clear_stats #=> nil + * + */ + +VALUE +rb_gc_clear_stats() +{ + gc_collections = 0; + gc_time = 0; + return Qnil; +} + +/* + * call-seq: + * GC.collections => Integer + * + * Returns the number of garbage collections performed while GC statistics collection + * was enabled. + * + * GC.collections #=> 35 + * + */ + +VALUE +rb_gc_collections() +{ + return INT2NUM(gc_collections); +} + +/* + * call-seq: + * GC.time => Integer + * + * Returns the time spent during garbage collection while GC statistics collection + * was enabled (in micro seconds). + * + * GC.time #=> 20000 + * + */ + +VALUE +rb_gc_time() +{ +#if HAVE_LONG_LONG + return LL2NUM(gc_time); +#else + return LONG2NUM(gc_time); +#endif +} + + VALUE rb_mGC; static struct gc_list { @@ -281,19 +395,19 @@ rb_gc_unregister_address(addr) struct gc_list *tmp = global_List; if (tmp->varptr == addr) { -global_List = tmp->next; -RUBY_CRITICAL(free(tmp)); -return; + global_List = tmp->next; + RUBY_CRITICAL(free(tmp)); + return; } while (tmp->next) { -if (tmp->next->varptr == addr) { struct gc_list *t = tmp->next; + if (tmp->next->varptr == addr) { + struct gc_list *t = tmp->next; -} -tmp + + + + + tmp->next = tmp->next->next; RUBY_CRITICAL(free(t)); break; = tmp->next; tmp->next = tmp->next->next; RUBY_CRITICAL(free(t)); break; } tmp = tmp->next; } } @@ -312,26 +426,26 @@ rb_global_variable(var) typedef struct RVALUE { union { -struct { unsigned long flags;/* always 0 for freed obj */ struct RVALUE *next; -} free; -struct RBasic basic; -struct RObject object; -struct RClass klass; -struct RFloat flonum; -struct RString string; -struct RArray array; -struct RRegexp regexp; -struct RHash hash; -struct RData data; -struct RStruct rstruct; -struct RBignum bignum; -struct RFile file; -struct RNode node; -struct RMatch match; -struct RVarmap varmap; -struct SCOPE scope; + struct { + unsigned long flags; /* always 0 for freed obj */ + struct RVALUE *next; + } free; + struct RBasic basic; + struct RObject object; + struct RClass klass; + struct RFloat flonum; + struct RString string; + struct RArray array; + struct RRegexp regexp; + struct RHash hash; + struct RData data; + struct RStruct rstruct; + struct RBignum bignum; + struct RFile file; + struct RNode node; + struct RMatch match; + struct RVarmap varmap; + struct SCOPE scope; } as; #ifdef GC_DEBUG char *file; @@ -346,7 +460,7 @@ typedef struct RVALUE { static RVALUE *freelist = 0; static RVALUE *deferred_final_list = 0; -#define HEAPS_INCREMENT 10 +static int heaps_increment = 10; static struct heaps_slot { void *membase; RVALUE *slot; @@ -355,45 +469,197 @@ static struct heaps_slot { static int heaps_length = 0; static int heaps_used = 0; -#define HEAP_MIN_SLOTS 10000 -static int heap_slots = HEAP_MIN_SLOTS; +static int heap_min_slots = 10000; +static int heap_slots = 10000; -#define FREE_MIN 4096 +static int heap_free_min = 4096; +static int heap_slots_increment = 10000; +static double heap_slots_growth_factor = 1.8; + +static long initial_malloc_limit = GC_MALLOC_LIMIT; + +static int verbose_gc_stats = Qfalse; + +static FILE* gc_data_file = NULL; static RVALUE *himem, *lomem; +static void set_gc_parameters() +{ + char *gc_stats_ptr, *min_slots_ptr, *free_min_ptr, *heap_slots_incr_ptr, + *heap_incr_ptr, *malloc_limit_ptr, *gc_heap_file_ptr, *heap_slots_growth_factor_ptr; + + gc_data_file = stderr; + + gc_stats_ptr = getenv("RUBY_GC_STATS"); + if (gc_stats_ptr != NULL) { + int gc_stats_i = atoi(gc_stats_ptr); + if (gc_stats_i > 0) { + verbose_gc_stats = Qtrue; + } + } + + gc_heap_file_ptr = getenv("RUBY_GC_DATA_FILE"); + if (gc_heap_file_ptr != NULL) { + FILE* data_file = fopen(gc_heap_file_ptr, "w"); + if (data_file != NULL) { + gc_data_file = data_file; + } + else { + fprintf(stderr, + "can't open gc log file %s for writing, using default\n", gc_heap_file_ptr); + } + } + + min_slots_ptr = getenv("RUBY_HEAP_MIN_SLOTS"); + if (min_slots_ptr != NULL) { + int min_slots_i = atoi(min_slots_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_MIN_SLOTS=%s\n", min_slots_ptr); + } + if (min_slots_i > 0) { + heap_slots = min_slots_i; + heap_min_slots = min_slots_i; + } + } + + free_min_ptr = getenv("RUBY_HEAP_FREE_MIN"); + if (free_min_ptr != NULL) { + int free_min_i = atoi(free_min_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_FREE_MIN=%s\n", free_min_ptr); + } + if (free_min_i > 0) { + heap_free_min = free_min_i; + } + } + + heap_incr_ptr = getenv("RUBY_HEAP_INCREMENT"); + if (heap_incr_ptr != NULL) { + int heap_incr_i = atoi(heap_incr_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_INCREMENT=%s\n", heap_incr_ptr); + } + if (heap_incr_i > 0) { + heaps_increment = heap_incr_i; + } + } + + heap_slots_incr_ptr = getenv("RUBY_HEAP_SLOTS_INCREMENT"); + if (heap_slots_incr_ptr != NULL) { + int heap_slots_incr_i = atoi(heap_slots_incr_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_SLOTS_INCREMENT=%s\n", heap_slots_incr_ptr); + } + if (heap_slots_incr_i > 0) { + heap_slots_increment = heap_slots_incr_i; + } + } + + heap_slots_growth_factor_ptr = getenv("RUBY_HEAP_SLOTS_GROWTH_FACTOR"); + if (heap_slots_growth_factor_ptr != NULL) { + double heap_slots_growth_factor_d = atoi(heap_slots_growth_factor_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_SLOTS_GROWTH_FACTOR=%s\n", heap_slots_growth_factor_ptr); + } + if (heap_slots_growth_factor_d > 0) { + heap_slots_growth_factor = heap_slots_growth_factor_d; + } + } + + malloc_limit_ptr = getenv("RUBY_GC_MALLOC_LIMIT"); + if (malloc_limit_ptr != NULL) { + int malloc_limit_i = atol(malloc_limit_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_GC_MALLOC_LIMIT=%s\n", malloc_limit_ptr); + } + if (malloc_limit_i > 0) { + initial_malloc_limit = malloc_limit_i; + } + } +} + +/* + * call-seq: + * GC.dump => nil + * + * dumps information about the current GC data structures to the GC log file + * + * GC.dump #=> nil + * + */ + +VALUE +rb_gc_dump() +{ + int i; + + for (i = 0; i < heaps_used; i++) { + int heap_size = heaps[i].limit; + fprintf(gc_data_file, "HEAP[%2d]: size=%7d\n", i, heap_size); + } + + return Qnil; +} + +/* + * call-seq: + * GC.log String => String + * + * Logs string to the GC data file and returns it. + * + * GC.log "manual GC call" #=> "manual GC call" + * + */ + +VALUE +rb_gc_log(self, original_str) + VALUE self, original_str; +{ + if (original_str == Qnil) { + fprintf(gc_data_file, "\n"); + } + else { + VALUE str = StringValue(original_str); + char *p = RSTRING(str)->ptr; + fprintf(gc_data_file, "%s\n", p); + } + return original_str; +} + + static void add_heap() { RVALUE *p, *pend; if (heaps_used == heaps_length) { -/* Realloc heaps */ -struct heaps_slot *p; -int length; -heaps_length += HEAPS_INCREMENT; -length = heaps_length*sizeof(struct heaps_slot); -RUBY_CRITICAL( if (heaps_used > 0) { -p = (struct heaps_slot *)realloc(heaps, length); -if (p) heaps = p; } else { -p = heaps = (struct heaps_slot *)malloc(length); }); -if (p == 0) rb_memerror(); + /* Realloc heaps */ + struct heaps_slot *p; + int length; + + heaps_length += heaps_increment; + length = heaps_length*sizeof(struct heaps_slot); + RUBY_CRITICAL( + if (heaps_used > 0) { + p = (struct heaps_slot *)realloc(heaps, length); + if (p) heaps = p; + } + else { + p = heaps = (struct heaps_slot *)malloc(length); + }); + if (p == 0) rb_memerror(); } for (;;) { -RUBY_CRITICAL(p = (RVALUE*)malloc(sizeof(RVALUE)*(heap_slots+1))); -if (p == 0) { if (heap_slots == HEAP_MIN_SLOTS) { -rb_memerror(); } heap_slots = HEAP_MIN_SLOTS; continue; -} + RUBY_CRITICAL(p = (RVALUE*)malloc(sizeof(RVALUE)*(heap_slots+1))); + if (p == 0) { + if (heap_slots == heap_min_slots) { + rb_memerror(); + } + heap_slots = heap_min_slots; + continue; + } heaps[heaps_used].membase = p; if ((VALUE)p % sizeof(RVALUE) == 0) heap_slots += 1; @@ -401,25 +667,26 @@ add_heap() p = (RVALUE*)((VALUE)p + sizeof(RVALUE) - ((VALUE)p % sizeof(RVALUE))); heaps[heaps_used].slot = p; heaps[heaps_used].limit = heap_slots; -break; + break; } pend = p + heap_slots; if (lomem == 0 || lomem > p) lomem = p; if (himem < pend) himem = pend; heaps_used++; heap_slots *= 1.8; if (heap_slots <= 0) heap_slots = HEAP_MIN_SLOTS; + heap_slots += heap_slots_increment; + heap_slots_increment *= heap_slots_growth_factor; + if (heap_slots <= 0) heap_slots = heap_min_slots; while (p < pend) { -p->as.free.flags = 0; -p->as.free.next = freelist; -freelist = p; -p++; + p->as.free.flags = 0; + p->as.free.next = freelist; + freelist = p; + p++; } } #define RANY(o) ((RVALUE*)(o)) -int +int rb_during_gc() { return during_gc; @@ -431,7 +698,7 @@ rb_newobj() VALUE obj; if (during_gc) -rb_bug("object allocation during garbage collection phase"); + rb_bug("object allocation during garbage collection phase"); if (ruby_gc_stress || !freelist) garbage_collect(); @@ -580,13 +847,13 @@ rb_source_filename(f) st_data_t name; if (!st_lookup(source_filenames, (st_data_t)f, &name)) { -long len = strlen(f) + 1; -char *ptr = ALLOC_N(char, len + 1); -name = (st_data_t)ptr; -*ptr++ = 0; -MEMCPY(ptr, f, char, len); -st_add_direct(source_filenames, (st_data_t)ptr, name); -return ptr; + long len = strlen(f) + 1; + char *ptr = ALLOC_N(char, len + 1); + name = (st_data_t)ptr; + *ptr++ = 0; + MEMCPY(ptr, f, char, len); + st_add_direct(source_filenames, (st_data_t)ptr, name); + return ptr; } return (char *)name + 1; } @@ -596,7 +863,7 @@ mark_source_filename(f) char *f; { if (f) { -f[-1] = 1; + f[-1] = 1; } } @@ -605,12 +872,12 @@ sweep_source_filename(key, value) char *key, *value; { if (*value) { -*value = 0; -return ST_CONTINUE; + *value = 0; + return ST_CONTINUE; } else { -free(value); -return ST_DELETE; + free(value); + return ST_DELETE; } } @@ -625,14 +892,14 @@ gc_mark_all() init_mark_stack(); for (i = 0; i < heaps_used; i++) { -p = heaps[i].slot; pend = p + heaps[i].limit; -while (p < pend) { if ((p->as.basic.flags & FL_MARK) && -(p->as.basic.flags != FL_MARK)) { -gc_mark_children((VALUE)p, 0); } p++; -} + p = heaps[i].slot; pend = p + heaps[i].limit; + while (p < pend) { + if ((p->as.basic.flags & FL_MARK) && + (p->as.basic.flags != FL_MARK)) { + gc_mark_children((VALUE)p, 0); + } + p++; + } } } @@ -647,8 +914,8 @@ gc_mark_rest() init_mark_stack(); while(p != tmp_arry){ -p--; -gc_mark_children(*p, 0); + + p--; gc_mark_children(*p, 0); } } @@ -665,9 +932,9 @@ is_pointer_to_heap(ptr) /* check if p looks like a pointer */ for (i=0; i < heaps_used; i++) { -heap_org = heaps[i].slot; -if (heap_org <= p && p < heap_org + heaps[i].limit) return Qtrue; + heap_org = heaps[i].slot; + if (heap_org <= p && p < heap_org + heaps[i].limit) + return Qtrue; } return Qfalse; } @@ -680,10 +947,10 @@ mark_locations_array(x, n) VALUE v; while (n--) { v = *x; -if (is_pointer_to_heap((void *)v)) { gc_mark(v, 0); -} -x++; + if (is_pointer_to_heap((void *)v)) { + gc_mark(v, 0); + } + x++; } } @@ -780,7 +1047,7 @@ rb_gc_mark_maybe(obj) VALUE obj; { if (is_pointer_to_heap((void *)obj)) { -gc_mark(obj, 0); + gc_mark(obj, 0); } } @@ -828,7 +1095,7 @@ gc_mark_children(ptr, lev) { register RVALUE *obj = RANY(ptr); + goto marking;/* skip */ goto marking; /* skip */ again: obj = RANY(ptr); @@ -839,148 +1106,148 @@ gc_mark_children(ptr, lev) marking: if (FL_TEST(obj, FL_EXIVAR)) { -rb_mark_generic_ivar(ptr); + rb_mark_generic_ivar(ptr); } switch (obj->as.basic.flags & T_MASK) { case T_NIL: case T_FIXNUM: -rb_bug("rb_gc_mark() called for broken object"); -break; + rb_bug("rb_gc_mark() called for broken object"); + break; case T_NODE: -mark_source_filename(obj->as.node.nd_file); -switch (nd_type(obj)) { - case NODE_IF:/* 1,2,3 */ - case NODE_FOR: - case NODE_ITER: - case NODE_CREF: - case NODE_WHEN: - case NODE_MASGN: - case NODE_RESCUE: - case NODE_RESBODY: - case NODE_CLASS: gc_mark((VALUE)obj->as.node.u2.node, lev); /* fall through */ - case NODE_BLOCK:/* 1,3 */ - case NODE_ARRAY: - case NODE_DSTR: - case NODE_DXSTR: - case NODE_DREGX: - case NODE_DREGX_ONCE: - case NODE_FBODY: - case NODE_ENSURE: - case NODE_CALL: - case NODE_DEFS: - case NODE_OP_ASGN1: gc_mark((VALUE)obj->as.node.u1.node, lev); /* fall through */ - case NODE_SUPER:/* 3 */ - case NODE_FCALL: - case NODE_DEFN: - case NODE_NEWLINE: ptr = (VALUE)obj->as.node.u3.node; goto again; - case NODE_WHILE:/* 1,2 */ - case NODE_UNTIL: - case NODE_AND: - case NODE_OR: - case NODE_CASE: - case NODE_SCLASS: - case NODE_DOT2: - case NODE_DOT3: - case NODE_FLIP2: - case NODE_FLIP3: - case NODE_MATCH2: - case NODE_MATCH3: - case NODE_OP_ASGN_OR: - case NODE_OP_ASGN_AND: - case NODE_MODULE: - case NODE_ALIAS: - case NODE_VALIAS: - case NODE_ARGS: gc_mark((VALUE)obj->as.node.u1.node, lev); /* fall through */ - case NODE_METHOD:/* 2 */ - case NODE_NOT: - case NODE_GASGN: - case NODE_LASGN: - case NODE_DASGN: - case NODE_DASGN_CURR: - case NODE_IASGN: - case NODE_CVDECL: - case NODE_CVASGN: - case NODE_COLON3: - case NODE_OPT_N: - case NODE_EVSTR: - case NODE_UNDEF: ptr = (VALUE)obj->as.node.u2.node; goto again; - case NODE_HASH:/* 1 */ - case NODE_LIT: - case NODE_STR: - case NODE_XSTR: - case NODE_DEFINED: - case NODE_MATCH: - case NODE_RETURN: - case NODE_BREAK: - case NODE_NEXT: - case NODE_YIELD: - case NODE_COLON2: - case NODE_SPLAT: - case NODE_TO_ARY: - case NODE_SVALUE: ptr = (VALUE)obj->as.node.u1.node; goto again; - case NODE_SCOPE:/* 2,3 */ - case NODE_BLOCK_PASS: - case NODE_CDECL: gc_mark((VALUE)obj->as.node.u3.node, lev); ptr = (VALUE)obj->as.node.u2.node; goto again; - case NODE_ZARRAY:/* - */ - case NODE_ZSUPER: - case NODE_CFUNC: - case NODE_VCALL: - case NODE_GVAR: - case NODE_LVAR: - case NODE_DVAR: - case NODE_IVAR: - case NODE_CVAR: - case NODE_NTH_REF: - case NODE_BACK_REF: - case NODE_REDO: - case NODE_RETRY: - case NODE_SELF: - case NODE_NIL: - case NODE_TRUE: - case NODE_FALSE: - case NODE_ATTRSET: - case NODE_BLOCK_ARG: - case NODE_POSTEXE: break; - case NODE_ALLOCA: mark_locations_array((VALUE*)obj->as.node.u1.value, - obj->as.node.u3.cnt); ptr = (VALUE)obj->as.node.u2.node; goto again; - default:/* unlisted NODE */ if (is_pointer_to_heap(obj->as.node.u1.node)) { -gc_mark((VALUE)obj->as.node.u1.node, lev); } if (is_pointer_to_heap(obj->as.node.u2.node)) { -gc_mark((VALUE)obj->as.node.u2.node, lev); } if (is_pointer_to_heap(obj->as.node.u3.node)) { -gc_mark((VALUE)obj->as.node.u3.node, lev); } -} -return;/* no need to mark class. */ + mark_source_filename(obj->as.node.nd_file); + switch (nd_type(obj)) { + case NODE_IF: /* 1,2,3 */ + case NODE_FOR: + case NODE_ITER: + case NODE_CREF: + case NODE_WHEN: + case NODE_MASGN: + case NODE_RESCUE: + case NODE_RESBODY: + case NODE_CLASS: + gc_mark((VALUE)obj->as.node.u2.node, lev); + /* fall through */ + case NODE_BLOCK: /* 1,3 */ + case NODE_ARRAY: + case NODE_DSTR: + case NODE_DXSTR: + case NODE_DREGX: + case NODE_DREGX_ONCE: + case NODE_FBODY: + case NODE_ENSURE: + case NODE_CALL: + case NODE_DEFS: + case NODE_OP_ASGN1: + gc_mark((VALUE)obj->as.node.u1.node, lev); + /* fall through */ + case NODE_SUPER: /* 3 */ + case NODE_FCALL: + case NODE_DEFN: + case NODE_NEWLINE: + ptr = (VALUE)obj->as.node.u3.node; + goto again; + + case NODE_WHILE: /* 1,2 */ + case NODE_UNTIL: + case NODE_AND: + case NODE_OR: + case NODE_CASE: + case NODE_SCLASS: + case NODE_DOT2: + case NODE_DOT3: + case NODE_FLIP2: + case NODE_FLIP3: + case NODE_MATCH2: + case NODE_MATCH3: + case NODE_OP_ASGN_OR: + case NODE_OP_ASGN_AND: + case NODE_MODULE: + case NODE_ALIAS: + case NODE_VALIAS: + case NODE_ARGS: + gc_mark((VALUE)obj->as.node.u1.node, lev); + /* fall through */ + case NODE_METHOD: /* 2 */ + case NODE_NOT: + case NODE_GASGN: + case NODE_LASGN: + case NODE_DASGN: + case NODE_DASGN_CURR: + case NODE_IASGN: + case NODE_CVDECL: + case NODE_CVASGN: + case NODE_COLON3: + case NODE_OPT_N: + case NODE_EVSTR: + case NODE_UNDEF: + ptr = (VALUE)obj->as.node.u2.node; + goto again; + + case NODE_HASH: /* 1 */ + case NODE_LIT: + case NODE_STR: + case NODE_XSTR: + case NODE_DEFINED: + case NODE_MATCH: + case NODE_RETURN: + case NODE_BREAK: + case NODE_NEXT: + case NODE_YIELD: + case NODE_COLON2: + case NODE_SPLAT: + case NODE_TO_ARY: + case NODE_SVALUE: + ptr = (VALUE)obj->as.node.u1.node; + goto again; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + case NODE_SCOPE: /* 2,3 */ case NODE_BLOCK_PASS: case NODE_CDECL: gc_mark((VALUE)obj->as.node.u3.node, lev); ptr = (VALUE)obj->as.node.u2.node; goto again; case NODE_ZARRAY: /* - */ case NODE_ZSUPER: case NODE_CFUNC: case NODE_VCALL: case NODE_GVAR: case NODE_LVAR: case NODE_DVAR: case NODE_IVAR: case NODE_CVAR: case NODE_NTH_REF: case NODE_BACK_REF: case NODE_REDO: case NODE_RETRY: case NODE_SELF: case NODE_NIL: case NODE_TRUE: case NODE_FALSE: case NODE_ATTRSET: case NODE_BLOCK_ARG: case NODE_POSTEXE: break; case NODE_ALLOCA: mark_locations_array((VALUE*)obj->as.node.u1.value, obj->as.node.u3.cnt); ptr = (VALUE)obj->as.node.u2.node; goto again; default: /* unlisted NODE */ if (is_pointer_to_heap(obj->as.node.u1.node)) { gc_mark((VALUE)obj->as.node.u1.node, lev); } if (is_pointer_to_heap(obj->as.node.u2.node)) { gc_mark((VALUE)obj->as.node.u2.node, lev); } if (is_pointer_to_heap(obj->as.node.u3.node)) { gc_mark((VALUE)obj->as.node.u3.node, lev); } } return; /* no need to mark class. */ } gc_mark(obj->as.basic.klass, lev); @@ -988,92 +1255,92 @@ gc_mark_children(ptr, lev) case T_ICLASS: case T_CLASS: case T_MODULE: -mark_tbl(obj->as.klass.m_tbl, lev); -mark_tbl(obj->as.klass.iv_tbl, lev); -ptr = obj->as.klass.super; -goto again; + mark_tbl(obj->as.klass.m_tbl, lev); + mark_tbl(obj->as.klass.iv_tbl, lev); + ptr = obj->as.klass.super; + goto again; case T_ARRAY: -if (FL_TEST(obj, ELTS_SHARED)) { ptr = obj->as.array.aux.shared; goto again; -} -else { long i, len = obj->as.array.len; VALUE *ptr = obj->as.array.ptr; + if (FL_TEST(obj, ELTS_SHARED)) { + ptr = obj->as.array.aux.shared; + goto again; + } + else { + long i, len = obj->as.array.len; + VALUE *ptr = obj->as.array.ptr; for (i=0; i -gc_mark(*ptr++, } -} -break; + for + + } + } + break; < len; i++) { lev); (i=0; i < len; i++) { gc_mark(*ptr++, lev); case T_HASH: -mark_hash(obj->as.hash.tbl, lev); -ptr = obj->as.hash.ifnone; -goto again; + mark_hash(obj->as.hash.tbl, lev); + + ptr = obj->as.hash.ifnone; goto again; case T_STRING: #define STR_ASSOC FL_USER3 /* copied from string.c */ -if (FL_TEST(obj, ELTS_SHARED|STR_ASSOC)) { ptr = obj->as.string.aux.shared; goto again; -} -break; + if (FL_TEST(obj, ELTS_SHARED|STR_ASSOC)) { + ptr = obj->as.string.aux.shared; + goto again; + } + break; case T_DATA: -if (obj->as.data.dmark) (*obj->as.data.dmark)(DATA_PTR(obj)); -break; + if (obj->as.data.dmark) (*obj->as.data.dmark)(DATA_PTR(obj)); + break; case T_OBJECT: -mark_tbl(obj->as.object.iv_tbl, lev); -break; + mark_tbl(obj->as.object.iv_tbl, lev); + break; case case case case case -break; + T_FILE: T_REGEXP: T_FLOAT: T_BIGNUM: T_BLKTAG: break; case T_MATCH: -if (obj->as.match.str) { ptr = obj->as.match.str; goto again; -} -break; + if (obj->as.match.str) { + ptr = obj->as.match.str; + goto again; + } + break; case T_VARMAP: -gc_mark(obj->as.varmap.val, lev); -ptr = (VALUE)obj->as.varmap.next; -goto again; + gc_mark(obj->as.varmap.val, lev); + ptr = (VALUE)obj->as.varmap.next; + goto again; case T_SCOPE: -if (obj->as.scope.local_vars && (obj->as.scope.flags & SCOPE_MALLOC)) { int n = obj->as.scope.local_tbl[0]+1; VALUE *vars = &obj->as.scope.local_vars[-1]; + if (obj->as.scope.local_vars && (obj->as.scope.flags & SCOPE_MALLOC)) { + int n = obj->as.scope.local_tbl[0]+1; + VALUE *vars = &obj->as.scope.local_vars[-1]; while (n--) { -gc_mark(*vars++, lev); } -} -break; + while (n--) { + gc_mark(*vars++, lev); + } + } + break; case T_STRUCT: -{ + + + long len = obj->as.rstruct.len; VALUE *ptr = obj->as.rstruct.ptr; { long len = obj->as.rstruct.len; VALUE *ptr = obj->as.rstruct.ptr; while (len--) { -gc_mark(*ptr++, lev); } -} -break; + while (len--) { + gc_mark(*ptr++, lev); + } + } + break; default: -rb_bug("rb_gc_mark(): unknown data type 0x%lx(0x%lx) %s", obj->as.basic.flags & T_MASK, obj, is_pointer_to_heap(obj) ? "corrupted object" : "non object"); + rb_bug("rb_gc_mark(): unknown data type 0x%lx(0x%lx) %s", + obj->as.basic.flags & T_MASK, obj, + is_pointer_to_heap(obj) ? "corrupted object" : "non object"); } } @@ -1102,22 +1369,55 @@ finalize_list(p) } } +static char* obj_type(int tp) +{ + switch (tp) { + case T_NIL : return "NIL"; + case T_OBJECT : return "OBJECT"; + case T_CLASS : return "CLASS"; + case T_ICLASS : return "ICLASS"; + case T_MODULE : return "MODULE"; + case T_FLOAT : return "FLOAT"; + case T_STRING : return "STRING"; + case T_REGEXP : return "REGEXP"; + case T_ARRAY : return "ARRAY"; + case T_FIXNUM : return "FIXNUM"; + case T_HASH : return "HASH"; + case T_STRUCT : return "STRUCT"; + case T_BIGNUM : return "BIGNUM"; + case T_FILE : return "FILE"; + + case T_TRUE : return "TRUE"; + case T_FALSE : return "FALSE"; + case T_DATA : return "DATA"; + case T_MATCH : return "MATCH"; + case T_SYMBOL : return "SYMBOL"; + + case T_BLKTAG : return "BLKTAG"; + case T_UNDEF : return "UNDEF"; + case T_VARMAP : return "VARMAP"; + case T_SCOPE : return "SCOPE"; + case T_NODE : return "NODE"; + default: return "____"; + } +} + static void free_unused_heaps() { int i, j; for (i = j = 1; j < heaps_used; i++) { -if (heaps[i].limit == 0) { free(heaps[i].membase); heaps_used--; -} -else { if (i != j) { -heaps[j] = heaps[i]; } j++; -} + if (heaps[i].limit == 0) { + free(heaps[i].membase); + heaps_used--; + } + else { + if (i != j) { + heaps[j] = heaps[i]; + } + j++; + } } } @@ -1134,24 +1434,33 @@ gc_sweep() unsigned long live = 0; unsigned long free_min = 0; + + + + + + + + + + unsigned long really_freed = 0; int free_counts[256]; int live_counts[256]; int do_gc_stats = gc_statistics & verbose_gc_stats; for (i = 0; i < heaps_used; i++) { free_min += heaps[i].limit; } free_min = free_min * 0.2; if (free_min < FREE_MIN) free_min = FREE_MIN; if (free_min < heap_free_min) free_min = heap_free_min; if (do_gc_stats) { for (i = 0 ; i< 256; i++) { free_counts[i] = live_counts[i] = 0; } + } if (ruby_in_compile && ruby_parser_stack_on_heap()) { -/* should not reclaim nodes during compilation + /* should not reclaim nodes during compilation if yacc's semantic stack is not allocated on machine stack */ -for (i = 0; i < heaps_used; i++) { p = heaps[i].slot; pend = p + heaps[i].limit; while (p < pend) { -if (!(p->as.basic.flags&FL_MARK) && BUILTIN_TYPE(p) == T_NODE) gc_mark((VALUE)p, 0); -p++; } -} + for (i = 0; i < heaps_used; i++) { + p = heaps[i].slot; pend = p + heaps[i].limit; + while (p < pend) { + if (!(p->as.basic.flags&FL_MARK) && BUILTIN_TYPE(p) == T_NODE) + gc_mark((VALUE)p, 0); + p++; + } + } } mark_source_filename(ruby_sourcefile); @@ -1172,7 +1481,7 @@ gc_sweep() while (p < pend) { if (!(p->as.basic.flags & FL_MARK)) { if (p->as.basic.flags && ((deferred = obj_free((VALUE)p)) || + (((do_gc_stats && really_freed++), deferred = obj_free((VALUE)p)) || ((FL_TEST(p, FL_FINALIZE)) && need_call_final))) { if (!deferred) { p->as.free.flags = T_DEFERRED; @@ -1183,6 +1492,12 @@ gc_sweep() final_list = p; } else { + if (do_gc_stats) { + int obt = p->as.basic.flags & T_MASK; + if (obt) { + free_counts[obt]++; + } + } add_freelist(p); } n++; @@ -1194,6 +1509,9 @@ gc_sweep() else { RBASIC(p)->flags &= ~FL_MARK; live++; + if (do_gc_stats) { + live_counts[RANY((VALUE)p)->as.basic.flags & T_MASK]++; + } } p++; } @@ -1211,15 +1529,29 @@ gc_sweep() } } if (malloc_increase > malloc_limit) { -malloc_limit += (malloc_increase - malloc_limit) * (double)live / (live + freed); -if (malloc_limit < GC_MALLOC_LIMIT) malloc_limit = GC_MALLOC_LIMIT; + malloc_limit += (malloc_increase - malloc_limit) * (double)live / (live + freed); + if (malloc_limit < initial_malloc_limit) malloc_limit = initial_malloc_limit; } malloc_increase = 0; if (freed < free_min) { -add_heap(); + add_heap(); } during_gc = 0; + + + + + + + + + + + + + + if (do_gc_stats) { fprintf(gc_data_file, "objects processed: %.7d\n", live+freed); fprintf(gc_data_file, "live objects : %.7d\n", live); fprintf(gc_data_file, "freelist objects : %.7d\n", freed - really_freed); fprintf(gc_data_file, "freed objects : %.7d\n", really_freed); for(i=0; i<256; i++) { if (free_counts[i]>0 || live_counts[i]>0) { fprintf(gc_data_file, "kept %.7d / freed %.7d objects of type %s\n", live_counts[i], free_counts[i], obj_type(i)); } } } /* clear finalization list */ if (final_list) { deferred_final_list = final_list; @@ -1260,51 +1592,51 @@ obj_free(obj) case T_FIXNUM: case T_TRUE: case T_FALSE: -rb_bug("obj_free() called for broken object"); -break; + + } rb_bug("obj_free() called for broken object"); break; if (FL_TEST(obj, FL_EXIVAR)) { -rb_free_generic_ivar((VALUE)obj); + rb_free_generic_ivar((VALUE)obj); } switch (BUILTIN_TYPE(obj)) { case T_OBJECT: -if (RANY(obj)->as.object.iv_tbl) { st_free_table(RANY(obj)->as.object.iv_tbl); -} -break; + if (RANY(obj)->as.object.iv_tbl) { + st_free_table(RANY(obj)->as.object.iv_tbl); + } + break; case T_MODULE: case T_CLASS: -rb_clear_cache_by_class((VALUE)obj); -st_free_table(RANY(obj)->as.klass.m_tbl); -if (RANY(obj)->as.object.iv_tbl) { st_free_table(RANY(obj)->as.object.iv_tbl); -} -break; + rb_clear_cache_by_class((VALUE)obj); + st_free_table(RANY(obj)->as.klass.m_tbl); + if (RANY(obj)->as.object.iv_tbl) { + st_free_table(RANY(obj)->as.object.iv_tbl); + } + break; case T_STRING: -if (RANY(obj)->as.string.ptr && !FL_TEST(obj, ELTS_SHARED)) { RUBY_CRITICAL(free(RANY(obj)->as.string.ptr)); -} -break; + if (RANY(obj)->as.string.ptr && !FL_TEST(obj, ELTS_SHARED)) { + RUBY_CRITICAL(free(RANY(obj)->as.string.ptr)); + } + break; case T_ARRAY: -if (RANY(obj)->as.array.ptr && !FL_TEST(obj, ELTS_SHARED)) { RUBY_CRITICAL(free(RANY(obj)->as.array.ptr)); -} -break; + if (RANY(obj)->as.array.ptr && !FL_TEST(obj, ELTS_SHARED)) { + RUBY_CRITICAL(free(RANY(obj)->as.array.ptr)); + } + break; case T_HASH: -if (RANY(obj)->as.hash.tbl) { st_free_table(RANY(obj)->as.hash.tbl); -} -break; + if (RANY(obj)->as.hash.tbl) { + st_free_table(RANY(obj)->as.hash.tbl); + } + break; case T_REGEXP: -if (RANY(obj)->as.regexp.ptr) { re_free_pattern(RANY(obj)->as.regexp.ptr); -} -if (RANY(obj)->as.regexp.str) { RUBY_CRITICAL(free(RANY(obj)->as.regexp.str)); -} -break; + if (RANY(obj)->as.regexp.ptr) { + re_free_pattern(RANY(obj)->as.regexp.ptr); + } + if (RANY(obj)->as.regexp.str) { + RUBY_CRITICAL(free(RANY(obj)->as.regexp.str)); + } + break; case T_DATA: if (DATA_PTR(obj)) { if ((long)RANY(obj)->as.data.dfree == -1) { @@ -1317,11 +1649,11 @@ obj_free(obj) } break; case T_MATCH: -if (RANY(obj)->as.match.regs) { re_free_registers(RANY(obj)->as.match.regs); RUBY_CRITICAL(free(RANY(obj)->as.match.regs)); -} -break; + if (RANY(obj)->as.match.regs) { + re_free_registers(RANY(obj)->as.match.regs); + RUBY_CRITICAL(free(RANY(obj)->as.match.regs)); + } + break; case T_FILE: if (RANY(obj)->as.file.fptr) { struct rb_io_t *fptr = RANY(obj)->as.file.fptr; @@ -1332,19 +1664,19 @@ obj_free(obj) } break; case T_ICLASS: -/* iClass shares table with the module */ -break; + /* iClass shares table with the module */ + break; case T_FLOAT: case T_VARMAP: case T_BLKTAG: -break; + break; case T_BIGNUM: -if (RANY(obj)->as.bignum.digits) { RUBY_CRITICAL(free(RANY(obj)->as.bignum.digits)); -} -break; + if (RANY(obj)->as.bignum.digits) { + RUBY_CRITICAL(free(RANY(obj)->as.bignum.digits)); + } + break; case T_NODE: switch (nd_type(obj)) { case NODE_SCOPE: @@ -1359,7 +1691,7 @@ obj_free(obj) break;/* no need to free iv_tbl */ case T_SCOPE: -if (RANY(obj)->as.scope.local_vars && + if (RANY(obj)->as.scope.local_vars && RANY(obj)->as.scope.flags != SCOPE_ALLOCA) { VALUE *vars = RANY(obj)->as.scope.local_vars-1; if (!(RANY(obj)->as.scope.flags & SCOPE_CLONE) && vars[0] == 0) @@ -1370,14 +1702,14 @@ obj_free(obj) break; case T_STRUCT: -if (RANY(obj)->as.rstruct.ptr) { RUBY_CRITICAL(free(RANY(obj)->as.rstruct.ptr)); -} -break; + if (RANY(obj)->as.rstruct.ptr) { + RUBY_CRITICAL(free(RANY(obj)->as.rstruct.ptr)); + } + break; default: -rb_bug("gc_sweep(): unknown data type 0x%lx(0x%lx)", RANY(obj)->as.basic.flags & T_MASK, obj); + rb_bug("gc_sweep(): unknown data type 0x%lx(0x%lx)", + RANY(obj)->as.basic.flags & T_MASK, obj); } return 0; @@ -1407,18 +1739,18 @@ _rb_setjmp:\n\ typedef unsigned long rb_jmp_buf[6]; __asm__ (".align 4\n\ _rb_setjmp:\n\ -pushl%ebp\n\ -movl%esp,%ebp\n\ -movl8(%ebp),%ebp\n\ -movl%eax,(%ebp)\n\ -movl%ebx,4(%ebp)\n\ -movl%ecx,8(%ebp)\n\ -movl%edx,12(%ebp)\n\ -movl%esi,16(%ebp)\n\ -movl%edi,20(%ebp)\n\ -popl%ebp\n\ -xorl%eax,%eax\n\ -ret"); + pushl %ebp\n\ + movl %esp,%ebp\n\ + movl 8(%ebp),%ebp\n\ + movl %eax,(%ebp)\n\ + movl %ebx,4(%ebp)\n\ + movl %ecx,8(%ebp)\n\ + movl %edx,12(%ebp)\n\ + movl %esi,16(%ebp)\n\ + movl %edi,20(%ebp)\n\ + popl %ebp\n\ + xorl %eax,%eax\n\ + ret"); #endif #endif int rb_setjmp (rb_jmp_buf); @@ -1431,41 +1763,50 @@ garbage_collect() struct gc_list *list; struct FRAME * volatile frame; /* gcc 2.7.2.3 -O2 bug?? jmp_buf save_regs_gc_mark; + struct timeval gctv1, gctv2; SET_STACK_END; */ #ifdef HAVE_NATIVETHREAD if (!is_ruby_native_thread()) { -rb_bug("cross-thread violation on rb_gc()"); + rb_bug("cross-thread violation on rb_gc()"); } #endif if (dont_gc || during_gc) { -if (!freelist) { add_heap(); -} -return; + if (!freelist) { + add_heap(); + } + return; } if (during_gc) return; during_gc++; + + + + + + + + if (gc_statistics) { gc_collections++; gettimeofday(&gctv1, NULL); if (verbose_gc_stats) { fprintf(gc_data_file, "Garbage collection started\n"); } } init_mark_stack(); gc_mark((VALUE)ruby_current_node, 0); /* mark frame stack */ for (frame = ruby_frame; frame; frame = frame->prev) { -rb_gc_mark_frame(frame); -if (frame->tmp) { struct FRAME *tmp = frame->tmp; while (tmp) { -rb_gc_mark_frame(tmp); -tmp = tmp->prev; } -} + rb_gc_mark_frame(frame); + if (frame->tmp) { + struct FRAME *tmp = frame->tmp; + while (tmp) { + rb_gc_mark_frame(tmp); + tmp = tmp->prev; + } + } } gc_mark((VALUE)ruby_scope, 0); gc_mark((VALUE)ruby_dyna_vars, 0); if (finalizer_table) { -mark_tbl(finalizer_table, 0); + mark_tbl(finalizer_table, 0); } FLUSH_REGISTER_WINDOWS; @@ -1478,9 +1819,9 @@ garbage_collect() rb_gc_mark_locations(rb_gc_stack_start, (VALUE*)STACK_END + 1); #else if ((VALUE*)STACK_END < rb_gc_stack_start) -rb_gc_mark_locations((VALUE*)STACK_END, rb_gc_stack_start); + rb_gc_mark_locations((VALUE*)STACK_END, rb_gc_stack_start); else -rb_gc_mark_locations(rb_gc_stack_start, (VALUE*)STACK_END + 1); + rb_gc_mark_locations(rb_gc_stack_start, (VALUE*)STACK_END + 1); #endif #ifdef __ia64 /* mark backing store (flushed register window on the stack) */ @@ -1489,13 +1830,13 @@ garbage_collect() #endif #if defined(__human68k__) || defined(__mc68000__) rb_gc_mark_locations((VALUE*)((char*)STACK_END + 2), - (VALUE*)((char*)rb_gc_stack_start + 2)); + (VALUE*)((char*)rb_gc_stack_start + 2)); #endif rb_gc_mark_threads(); /* mark protected global variables */ for (list = global_List; list; list = list->next) { -rb_gc_mark_maybe(*list->varptr); + rb_gc_mark_maybe(*list->varptr); } rb_mark_end_proc(); rb_gc_mark_global_tbl(); @@ -1510,18 +1851,30 @@ garbage_collect() /* gc_mark objects whose marking are not completed*/ do { -while (!MARK_STACK_EMPTY) { if (mark_stack_overflow){ -gc_mark_all(); } else { -gc_mark_rest(); } -} -rb_gc_abort_threads(); + while (!MARK_STACK_EMPTY) { + if (mark_stack_overflow){ + gc_mark_all(); + } + else { + gc_mark_rest(); + } + } + rb_gc_abort_threads(); } while (!MARK_STACK_EMPTY); gc_sweep(); + + + + + + + + + + + + if (gc_statistics) { GC_TIME_TYPE musecs_used; gettimeofday(&gctv2, NULL); musecs_used = ((GC_TIME_TYPE)(gctv2.tv_sec - gctv1.tv_sec) * 1000000) + (gctv2.tv_usec - gctv1.tv_usec); gc_time += musecs_used; if (verbose_gc_stats) { fprintf(gc_data_file, "GC time: %d msec\n", musecs_used / 1000); fflush(gc_data_file); } } } void @@ -1588,8 +1941,8 @@ Init_stack(addr) memset(&m, 0, sizeof(m)); VirtualQuery(&m, &m, sizeof(m)); rb_gc_stack_start = -STACK_UPPER((VALUE *)&m, (VALUE *)m.BaseAddress, (VALUE *)((char *)m.BaseAddress + m.RegionSize) - 1); + STACK_UPPER((VALUE *)&m, (VALUE *)m.BaseAddress, + (VALUE *)((char *)m.BaseAddress + m.RegionSize) - 1); #elif defined(STACK_END_ADDRESS) { extern void *STACK_END_ADDRESS; @@ -1599,24 +1952,24 @@ Init_stack(addr) if (!addr) addr = (void *)&addr; STACK_UPPER(&addr, addr, ++addr); if (rb_gc_stack_start) { -if (STACK_UPPER(&addr, -rb_gc_stack_start > addr, -rb_gc_stack_start < addr)) rb_gc_stack_start = addr; -return; + if (STACK_UPPER(&addr, + rb_gc_stack_start > addr, + rb_gc_stack_start < addr)) + rb_gc_stack_start = addr; + return; } rb_gc_stack_start = addr; #endif #ifdef HAVE_GETRLIMIT { -struct rlimit rlim; + struct rlimit rlim; -if (getrlimit(RLIMIT_STACK, &rlim) == 0) { unsigned int space = rlim.rlim_cur/5; + if (getrlimit(RLIMIT_STACK, &rlim) == 0) { + unsigned int space = rlim.rlim_cur/5; -} + + + if (space > 1024*1024) space = 1024*1024; STACK_LEVEL_MAX = (rlim.rlim_cur - space) / sizeof(VALUE); if (space > 1024*1024) space = 1024*1024; STACK_LEVEL_MAX = (rlim.rlim_cur - space) / sizeof(VALUE); } } #endif } @@ -1652,16 +2005,16 @@ void ruby_init_stack(VALUE *addr } #elif defined _WIN32 { -MEMORY_BASIC_INFORMATION mi; -DWORD size; -DWORD space; -if (VirtualQuery(&mi, &mi, sizeof(mi))) { size = (char *)mi.BaseAddress - (char *)mi.AllocationBase; space = size / 5; if (space > 1024*1024) space = 1024*1024; STACK_LEVEL_MAX = (size - space) / sizeof(VALUE); -} + MEMORY_BASIC_INFORMATION mi; + DWORD size; + + + + + + + + DWORD space; if (VirtualQuery(&mi, &mi, sizeof(mi))) { size = (char *)mi.BaseAddress - (char *)mi.AllocationBase; space = size / 5; if (space > 1024*1024) space = 1024*1024; STACK_LEVEL_MAX = (size - space) / sizeof(VALUE); } } #endif } @@ -1701,8 +2054,9 @@ void Init_heap() { if (!rb_gc_stack_start) { -Init_stack(0); + Init_stack(0); } + set_gc_parameters(); add_heap(); } @@ -1715,7 +2069,7 @@ os_obj_of(of) volatile VALUE v; for (i = 0; i < heaps_used; i++) { -RVALUE *p, *pend; + RVALUE *p, *pend; p = heaps[i].slot; pend = p + heaps[i].limit; for (;p < pend; p++) { @@ -1808,8 +2162,8 @@ add_final(os, block) { rb_warn("ObjectSpace::add_finalizer is deprecated; use define_finalizer"); if (!rb_respond_to(block, rb_intern("call"))) { -rb_raise(rb_eArgError, "wrong type argument %s (should be callable)", - rb_obj_classname(block)); + rb_raise(rb_eArgError, "wrong type argument %s (should be callable)", + rb_obj_classname(block)); } rb_ary_push(finalizers, block); return block; @@ -1864,7 +2218,7 @@ undefine_final(os, obj) VALUE os, obj; { if (finalizer_table) { -st_delete(finalizer_table, (st_data_t*)&obj, 0); + st_delete(finalizer_table, (st_data_t*)&obj, 0); } return obj; } @@ -1888,11 +2242,11 @@ define_final(argc, argv, os) rb_scan_args(argc, argv, "11", &obj, &block); if (argc == 1) { -block = rb_block_proc(); + block = rb_block_proc(); } else if (!rb_respond_to(block, rb_intern("call"))) { -rb_raise(rb_eArgError, "wrong type argument %s (should be callable)", - rb_obj_classname(block)); + rb_raise(rb_eArgError, "wrong type argument %s (should be callable)", + rb_obj_classname(block)); } need_call_final = 1; if (!FL_ABLE(obj)) { @@ -1905,10 +2259,10 @@ define_final(argc, argv, os) OBJ_FREEZE(block); if (!finalizer_table) { -finalizer_table = st_init_numtable(); + finalizer_table = st_init_numtable(); } if (st_lookup(finalizer_table, obj, &table)) { -rb_ary_push(table, block); + rb_ary_push(table, block); } else { table = rb_ary_new3(1, block); @@ -1927,7 +2281,7 @@ rb_gc_copy_finalizer(dest, obj) if (!finalizer_table) return; if (!FL_TEST(obj, FL_FINALIZE)) return; if (st_lookup(finalizer_table, obj, &table)) { -st_insert(finalizer_table, dest, table); + st_insert(finalizer_table, dest, table); } RBASIC(dest)->flags |= FL_FINALIZE; } @@ -1957,18 +2311,18 @@ run_final(obj) args[1] = 0; args[2] = (VALUE)ruby_safe_level; for (i=0; i<RARRAY(finalizers)->len; i++) { -args[0] = RARRAY(finalizers)->ptr[i]; -if (!args[1]) args[1] = rb_ary_new3(1, objid); -rb_protect((VALUE(*)_((VALUE)))run_single_final, (VALUE)args, &status); + + + args[0] = RARRAY(finalizers)->ptr[i]; if (!args[1]) args[1] = rb_ary_new3(1, objid); rb_protect((VALUE(*)_((VALUE)))run_single_final, (VALUE)args, &status); } if (finalizer_table && st_delete(finalizer_table, (st_data_t*)&obj, &table)) { -for (i=0; i<RARRAY(table)->len; i++) { VALUE final = RARRAY(table)->ptr[i]; args[0] = RARRAY(final)->ptr[1]; if (!args[1]) args[1] = rb_ary_new3(1, objid); args[2] = FIX2INT(RARRAY(final)->ptr[0]); rb_protect((VALUE(*)_((VALUE)))run_single_final, (VALUE)args, &status); -} + for (i=0; i<RARRAY(table)->len; i++) { + VALUE final = RARRAY(table)->ptr[i]; + args[0] = RARRAY(final)->ptr[1]; + if (!args[1]) args[1] = rb_ary_new3(1, objid); + args[2] = FIX2INT(RARRAY(final)->ptr[0]); + rb_protect((VALUE(*)_((VALUE)))run_single_final, (VALUE)args, &status); + } } rb_thread_critical = critical_save; } @@ -1980,8 +2334,8 @@ rb_gc_finalize_deferred() deferred_final_list = 0; if (p) { -finalize_list(p); -free_unused_heaps(); + finalize_list(p); + free_unused_heaps(); } } @@ -2061,7 +2415,7 @@ id2ref(obj, objid) if (ptr == Qfalse) return Qfalse; if (ptr == Qnil) return Qnil; if (FIXNUM_P(ptr)) return (VALUE)ptr; ptr = objid ^ FIXNUM_FLAG;/* unset FIXNUM_FLAG */ + ptr = objid ^ FIXNUM_FLAG; /* unset FIXNUM_FLAG */ if ((ptr % sizeof(RVALUE)) == (4 << 2)) { ID symid = ptr / sizeof(RVALUE); @@ -2075,7 +2429,7 @@ id2ref(obj, objid) rb_raise(rb_eRangeError, "0x%lx is not id value", p0); } if (BUILTIN_TYPE(ptr) == 0 || RBASIC(ptr)->klass == 0) { -rb_raise(rb_eRangeError, "0x%lx is recycled object", p0); + rb_raise(rb_eRangeError, "0x%lx is recycled object", p0); } return (VALUE)ptr; } @@ -2166,6 +2520,14 @@ Init_GC() rb_define_singleton_method(rb_mGC, "stress=", gc_stress_set, 1); rb_define_method(rb_mGC, "garbage_collect", rb_gc_start, 0); + + + + + + + + rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, "enable_stats", rb_gc_enable_stats, 0); "disable_stats", rb_gc_disable_stats, 0); "clear_stats", rb_gc_clear_stats, 0); "collections", rb_gc_collections, 0); "time", rb_gc_time, 0); "dump", rb_gc_dump, 0); "log", rb_gc_log, 1); rb_mObSpace = rb_define_module("ObjectSpace"); rb_define_module_function(rb_mObSpace, "each_object", os_each_obj, -1); rb_define_module_function(rb_mObSpace, "garbage_collect", rb_gc_start, 0); @@ -2188,7 +2550,7 @@ Init_GC() + rb_global_variable(&nomem_error); nomem_error = rb_exc_new3(rb_eNoMemError, rb_obj_freeze(rb_str_new2("failed to allocate memory"))); rb_obj_freeze(rb_str_new2("failed to allocate memory"))); OBJ_TAINT(nomem_error); OBJ_FREEZE(nomem_error); 1.26.5.1.12.1.10. 08-fork-support-for-gc-logging.patch diff --git a/gc.c b/gc.c index 9ad716f..a3cbe91 100644 --- a/gc.c +++ b/gc.c @@ -223,6 +223,8 @@ static int dont_gc; static int gc_statistics = 0; static GC_TIME_TYPE gc_time = 0; static int gc_collections = 0; +static int verbose_gc_stats = Qfalse; +static FILE* gc_data_file = NULL; static int during_gc; static int need_call_final = 0; static st_table *finalizer_table = 0; @@ -368,9 +370,148 @@ rb_gc_time() #endif } VALUE rb_mGC; +/* + * call-seq: + * GC.enable_trace => true or false + * + * Enables garbage collection tracing, returning <code>true</code> if garbage + * collection tracing was already enabled. + * + * GC.enable_trace #=> false or true + * GC.enable_trace #=> true + * + */ + +VALUE +rb_gc_enable_trace() +{ + int old = verbose_gc_stats; + verbose_gc_stats = Qtrue; + return old; +} + +/* + * call-seq: + * GC.disable_trace => true or false + * + * Disables garbage collection tracing, returning <code>true</code> if garbage + * collection tracing was already disabled. + * + * GC.disable_trace #=> false or true + * GC.disable_trace #=> true + * + */ + +VALUE +rb_gc_disable_trace() +{ + int old = verbose_gc_stats; + verbose_gc_stats = Qfalse; + return old; +} + +char* GC_LOGFILE_IVAR = "@gc_logfile_name"; + +/* + * call-seq: + * GC.log_file(filename=nil, mode="w") => boolean + * + * Changes the GC data log file. Closes the currently open logfile. + * Returns true if the file was successfully opened for + * writing. Returns false if the file could not be opened for + * writing. Returns the name of the current logfile (or nil) if no + * parameter is given. Restores logging to stderr when given nil as + * an argument. + * + * GC.log_file #=> nil + * GC.log_file "/tmp/gc.log" #=> true + * GC.log_file #=> "/tmp/gc.log" + * GC.log_file nil #=> true + * + */ + +VALUE +rb_gc_log_file(int argc, VALUE *argv, VALUE self) +{ + VALUE filename = Qnil; + VALUE mode_str = Qnil; + FILE* f = NULL; + char* mode = "w"; + + VALUE current_logfile_name = rb_iv_get(rb_mGC, GC_LOGFILE_IVAR); + + if (argc==0) + return current_logfile_name; + + rb_scan_args(argc, argv, "02", &filename, &mode_str); + + if (filename == Qnil) { + /* close current logfile and reset logfile to stderr */ + if (gc_data_file != stderr) { + fclose(gc_data_file); + gc_data_file = stderr; + rb_iv_set(rb_mGC, GC_LOGFILE_IVAR, Qnil); + } + return Qtrue; + } + + /* we have a real logfile name */ + filename = StringValue(filename); + + if (rb_equal(current_logfile_name, filename) == Qtrue) { + /* do nothing if we get the file name we're already logging to */ + return Qtrue; + } + + /* get mode for file opening */ + if (mode_str != Qnil) + { + mode = RSTRING(StringValue(mode_str))->ptr; + } + + /* try to open file in given mode */ + if (f = fopen(RSTRING(filename)->ptr, mode)) { + if (gc_data_file != stderr) { + fclose(gc_data_file); + } + gc_data_file = f; + rb_iv_set(rb_mGC, GC_LOGFILE_IVAR, filename); + } else { + return Qfalse; + } + return Qtrue; +} + + +/* + * Called from process.c before a fork. Flushes the gc log file to + * avoid writing the buffered output twice (once in the parent, and + * once in the child). + */ +void +rb_gc_before_fork() +{ + /* flush gc log file */ + fflush(gc_data_file); +} + +/* + * Called from process.c after a fork in the child process. Turns off + * logging, disables GC stats and resets all gc counters and timing + * information. + */ +void +rb_gc_after_fork() +{ + rb_gc_disable_stats(); + rb_gc_clear_stats(); + rb_gc_disable_trace(); + gc_data_file = stderr; + rb_iv_set(rb_mGC, GC_LOGFILE_IVAR, Qnil); +} + static struct gc_list { VALUE *varptr; struct gc_list *next; @@ -477,10 +618,6 @@ static double heap_slots_growth_factor = 1.8; static long initial_malloc_limit = GC_MALLOC_LIMIT; -static int verbose_gc_stats = Qfalse; -static FILE* gc_data_file = NULL; static RVALUE *himem, *lomem; static void set_gc_parameters() @@ -496,6 +633,8 @@ static void set_gc_parameters() if (gc_stats_i > 0) { verbose_gc_stats = Qtrue; } + /* child processes should not inherit RUBY_GC_STATS */ + unsetenv("RUBY_GC_STATS"); } gc_heap_file_ptr = getenv("RUBY_GC_DATA_FILE"); @@ -508,6 +647,8 @@ static void set_gc_parameters() fprintf(stderr, "can't open gc log file %s for writing, using default\n", gc_heap_file_ptr); } /* child processes should not inherit RUBY_GC_DATA_FILE to avoid clobbering */ unsetenv("RUBY_GC_DATA_FILE"); + + } min_slots_ptr = getenv("RUBY_HEAP_MIN_SLOTS"); @@ -2619,6 +2760,9 @@ Init_GC() rb_define_singleton_method(rb_mGC, "dump_file_and_line_info", rb_gc_dump_file_and_line_info, -1); #endif rb_define_singleton_method(rb_mGC, "log", rb_gc_log, 1); + rb_define_singleton_method(rb_mGC, "log_file", rb_gc_log_file, -1); + rb_define_singleton_method(rb_mGC, "enable_trace", rb_gc_enable_trace, 0); + rb_define_singleton_method(rb_mGC, "disable_trace", rb_gc_disable_trace, 0); rb_mObSpace = rb_define_module("ObjectSpace"); rb_define_module_function(rb_mObSpace, "each_object", os_each_obj, -1); diff --git a/intern.h b/intern.h index acae58d..49e1827 100644 --- a/intern.h +++ b/intern.h @@ -270,6 +270,8 @@ void rb_gc_call_finalizer_at_exit _((void)); VALUE rb_gc_enable _((void)); VALUE rb_gc_disable _((void)); VALUE rb_gc_start _((void)); +void rb_gc_before_fork _((void)); +void rb_gc_after_fork _((void)); /* hash.c */ void st_foreach_safe _((struct st_table *, int (*)(ANYARGS), unsigned long)); void rb_hash_foreach _((VALUE, int (*)(ANYARGS), VALUE)); diff --git a/process.c b/process.c index 8f6285d..ea28cb8 100644 --- a/process.c +++ b/process.c @@ -1330,6 +1330,8 @@ rb_f_fork(obj) fflush(stderr); #endif + + rb_gc_before_fork(); before_exec(); pid = fork(); after_exec(); @@ -1339,6 +1341,7 @@ rb_f_fork(obj) #ifdef linux after_exec(); #endif + rb_gc_after_fork(); rb_thread_atfork(); if (rb_block_given_p()) { int status; @@ -1574,10 +1577,12 @@ rb_f_system(argc, argv) chfunc = signal(SIGCHLD, SIG_DFL); retry: + rb_gc_before_fork(); before_exec(); pid = fork(); if (pid == 0) { /* child process */ + rb_gc_after_fork(); rb_thread_atfork(); rb_protect(proc_exec_args, (VALUE)&earg, NULL); _exit(127); 1.26.5.1.12.1.11. 17-caller-for-all-threads.patch diff --git a/eval.c b/eval.c index 8a2f492..b34b60d 100644 --- a/eval.c +++ b/eval.c @@ -8199,6 +8199,17 @@ rb_f_method_name() } } +/* Hash (Thread => Backtrace) used to collect backtrace for each threads. */ +static VALUE backtrace_for_each_thread; + +static int backtrace_level_for_each_thread; + +static VALUE +switch_thread_context_to_collect_backtrace(rb_thread_t next); + +static VALUE +rb_f_caller_for_all_threads(); + void Init_eval() { @@ -8244,6 +8255,7 @@ Init_eval() rb_define_global_function("fail", rb_f_raise, -1); + rb_define_global_function("caller", rb_f_caller, -1); rb_define_global_function("caller_for_all_threads", rb_f_caller_for_all_threads, -1); rb_define_global_function("exit", rb_f_exit, -1); rb_define_global_function("abort", rb_f_abort, -1); @@ -10599,6 +10611,7 @@ static int th_sig, th_safe; #define RESTORE_RAISE5 #define RESTORE_SIGNAL6 #define RESTORE_EXIT7 +#define RESTORE_BACKTRACE8 extern VALUE *rb_gc_stack_start; #ifdef __ia64 @@ -10705,6 +10718,15 @@ rb_thread_switch(n) } rb_exc_raise(th_raise_exception); break; + case RESTORE_BACKTRACE: + rb_hash_aset(backtrace_for_each_thread, curr_thread->thread, + backtrace(backtrace_level_for_each_thread)); + if (curr_thread != main_thread) { + switch_thread_context_to_collect_backtrace(curr_thread->next); + } else { + /* Circled back to main thread, cycle is complete. */ + } + break; case RESTORE_NORMAL: default: break; @@ -13874,3 +13896,74 @@ rb_throw(tag, val) argv[1] = val; rb_f_throw(2, argv); } + +static VALUE +switch_thread_context_to_collect_backtrace(rb_thread_t next) +{ + if (THREAD_SAVE_CONTEXT(curr_thread)) { + return Qnil; + } + curr_thread = next; + rb_thread_restore_context(next, RESTORE_BACKTRACE); + return Qnil; +} + + +/* + * call-seq: + * caller_for_all_threads(start=1) => array + * + * Returns the current execution stack for all threads + * ---a hash whose keys are thread instances and values + * the thread caller backtrace. + * + * Backtraces are array of hashes indicating location on the + * stack. Hash keys include ``<em>:line</em>'' or ``<em>:file</em>'' + * and ``<em>:method'</em>''. + * + * The optional _start_ parameter + * determines the number of initial stack entries to omit from the + * result. + * + * def a(skip) + * caller_for_all_threads(skip) + * end + * def b(skip) + * a(skip) + * end + * def c(skip) + * b(skip) + * end + * c(0) #=> ["prog:2:in `a'", "prog:5:in `b'", "prog:8:in `c'", "prog:10"] + * c(1) #=> ["prog:5:in `b'", "prog:8:in `c'", "prog:11"] + * c(2) #=> ["prog:8:in `c'", "prog:12"] + * c(3) #=> ["prog:13"] + */ +static VALUE +rb_f_caller_for_all_threads(argc, argv) + int argc; + VALUE *argv; +{ + volatile int critical; + VALUE level; +VALUE result; + + rb_scan_args(argc, argv, "01", &level); + backtrace_level_for_each_thread = NIL_P(level) ? 0 : NUM2INT(level); +if (backtrace_level_for_each_thread < 0) { +rb_raise(rb_eArgError, "negative level (%d)", backtrace_level_for_each_thread); +} + +critical = rb_thread_critical; +rb_thread_critical = Qtrue; + + backtrace_for_each_thread = rb_hash_new(); + switch_thread_context_to_collect_backtrace(main_thread->next); + +result = backtrace_for_each_thread; +backtrace_for_each_thread = Qnil; +backtrace_for_each_thread = 0; + +rb_thread_critical = critical; + return result; +} diff --git a/test/callerforallthreads/test_caller_for_each_thread.rb b/test/callerforallthreads/test_caller_for_each_thread.rb new file mode 100644 index 0000000..6aebaed --- /dev/null +++ b/test/callerforallthreads/test_caller_for_each_thread.rb @@ -0,0 +1,95 @@ +# -*- ruby-indent-level: 4 -*+require 'thread' +require 'test/unit' + +class AClassWithNestedmethods + + def an_ultra_nested_method(skip) + caller_for_all_threads skip + end + + def a_nested_method(skip) + an_ultra_nested_method skip + end + + def a_method(skip=0) + a_nested_method skip + end + +end + +class CallerForEachThreadTest < Test::Unit::TestCase + + def testCollectMeaningfulBacktraceForASingleThread + backtraces = AClassWithNestedmethods.new.a_method + backtrace = backtraces[Thread.current] + assert_not_nil backtrace + assert_equal __FILE__ + ":8:in `an_ultra_nested_method'", backtrace[0] + assert_equal __FILE__ + ":12:in `a_nested_method'", backtrace[1] + assert_equal __FILE__ + ":16:in `a_method'", backtrace[2] + assert_equal __FILE__ + ":24:in `testCollectMeaningfulBacktraceForASingleThread'", + backtrace[3] + end + + def testCanSkipFirstStackEntries + backtraces = AClassWithNestedmethods.new.a_method 2 + backtrace = backtraces[Thread.current] + assert_not_nil backtrace + assert_equal __FILE__ + ":16:in `a_method'", backtrace[0] + assert_equal __FILE__ + ":35:in `testCanSkipFirstStackEntries'", + backtrace[1] + end + + def testCollectMeaningfulBacktraceForMultipleThreads + first_thread = Thread.new do + loop do + Thread.pass + sleep 1 + end + end + + second_thread = Thread.new do + loop do + Thread.pass + sleep 1 + end + end + + backtraces = AClassWithNestedmethods.new.a_method + + backtrace = backtraces[Thread.current] + assert_not_nil backtrace + assert_match __FILE__ + ":8:in `an_ultra_nested_method'", backtrace[0] + assert_match __FILE__ + ":12:in `a_nested_method'", backtrace[1] + assert_equal __FILE__ + ":16:in `a_method'", backtrace[2] + assert_equal __FILE__ + ":58:in `testCollectMeaningfulBacktraceForMultipleThreads'", + backtrace[3] + + backtrace = backtraces[first_thread] + assert_not_nil backtrace + assert_equal __FILE__ + ":47:in `testCollectMeaningfulBacktraceForMultipleThreads'", + backtrace[0] + assert_equal __FILE__ + ":45:in `loop'", + backtrace[1] + assert_equal __FILE__ + ":45:in `testCollectMeaningfulBacktraceForMultipleThreads'", + backtrace[2] + assert_equal __FILE__ + ":44:in `initialize'",backtrace[3] + assert_equal __FILE__ + ":44:in `new'", backtrace[4] + assert_equal __FILE__ + ":44:in `testCollectMeaningfulBacktraceForMultipleThreads'", + backtrace[5] + + backtrace = backtraces[second_thread] + assert_not_nil backtrace + assert_equal __FILE__ + ":53:in `testCollectMeaningfulBacktraceForMultipleThreads'", + backtrace[0] + assert_equal __FILE__ + ":52:in `loop'", backtrace[1] + assert_equal __FILE__ + ":52:in `testCollectMeaningfulBacktraceForMultipleThreads'", + backtrace[2] + assert_equal __FILE__ + ":51:in `initialize'",backtrace[3] + assert_equal __FILE__ + ":51:in `new'", backtrace[4] + assert_equal __FILE__ + ":51:in `testCollectMeaningfulBacktraceForMultipleThreads'", + backtrace[5] + end + +end + 1.26.5.1.12.1.12. 11-expose-heap-slots.patch diff --git a/gc.c b/gc.c index 5b42b90..21b3f6b 100644 --- a/gc.c +++ b/gc.c @@ -690,6 +690,7 @@ static int heaps_used = 0; static int heap_min_slots = 10000; static int heap_slots = 10000; +static int heap_size = 0; static int heap_free_min = 4096; static int heap_slots_increment = 10000; @@ -800,6 +801,21 @@ static void set_gc_parameters() /* * call-seq: + * GC.heap_slots => Integer + * + * Returns the number of heap slots available for object allocations. + * + * GC.heap_slots #=> 10000 + * + */ +VALUE +rb_gc_heap_slots() +{ + return INT2NUM(heap_size); +} + +/* + * call-seq: * GC.dump => nil * * dumps information about the current GC data structures to the GC log file @@ -967,6 +983,7 @@ add_heap() heaps[heaps_used].limit = heap_slots; break; } + heap_size += heap_slots; pend = p + heap_slots; if (lomem == 0 || lomem > p) lomem = p; if (himem < pend) himem = pend; @@ -1828,6 +1845,7 @@ gc_sweep() if (n == heaps[i].limit && freed > free_min) { RVALUE *pp; + heap_size -= n; heaps[i].limit = 0; for (pp = final_list; pp != final; pp = pp->as.free.next) { pp->as.free.flags |= FL_SINGLETON; /* freeing page mark */ @@ -2866,6 +2884,7 @@ Init_GC() rb_define_singleton_method(rb_mGC, "clear_stats", rb_gc_clear_stats, 0); rb_define_singleton_method(rb_mGC, "allocated_size", rb_gc_allocated_size, 0); rb_define_singleton_method(rb_mGC, "num_allocations", rb_gc_num_allocations, 0); + rb_define_singleton_method(rb_mGC, "heap_slots", rb_gc_heap_slots, 0); rb_define_singleton_method(rb_mGC, "collections", rb_gc_collections, 0); rb_define_singleton_method(rb_mGC, "time", rb_gc_time, 0); rb_define_singleton_method(rb_mGC, "dump", rb_gc_dump, 0); diff --git a/intern.h b/intern.h index 86b4395..e23d2d7 100644 --- a/intern.h +++ b/intern.h @@ -274,6 +274,7 @@ void rb_gc_before_fork _((void)); void rb_gc_after_fork _((void)); VALUE rb_gc_allocated_size _((void)); VALUE rb_gc_num_allocations _((void)); +VALUE rb_gc_heap_slots _((void)); unsigned long rb_os_live_objects _((void)); #ifdef HAVE_LONG_LONG unsigned LONG_LONG rb_os_allocated_objects _((void)); 1.26.5.1.12.1.13. 03-sigvtalrm-fix.patch diff --git a/eval.c b/eval.c index 284e486..00bcd36 100644 --- a/eval.c +++ b/eval.c @@ -12461,6 +12461,11 @@ rb_thread_start_0(fn, arg, th) curr_thread->next = th; th->priority = curr_thread->priority; th->thgroup = curr_thread->thgroup; +#if defined(HAVE_SETITIMER) || defined(_THREAD_SAFE) + if (!thread_init) { + rb_thread_start_timer(); + } +#endif } START_TIMER(); @@ -13188,7 +13193,9 @@ rb_thread_atfork() main_thread = curr_thread; curr_thread->next = curr_thread; curr_thread->prev = curr_thread; STOP_TIMER(); +#if defined(HAVE_SETITIMER) || defined(_THREAD_SAFE) + rb_thread_stop_timer(); +#endif } 1.26.5.1.12.1.14. 07-heap-dump-support.patch diff --git a/configure.in b/configure.in index 7368808..ffe0649 100644 --- a/configure.in +++ b/configure.in @@ -1609,6 +1609,14 @@ fi LDFLAGS="-L. $LDFLAGS" AC_SUBST(ARCHFILE) +dnl enable gc debugging +AC_ARG_ENABLE(gcdebug, + [ --enable-gcdebug build garbage collector with debugging enabled. ], + [enable_gcdebug=$enableval]) +if test "$enable_gcdebug" = 'yes'; then + AC_DEFINE(GC_DEBUG, 1) +fi + dnl build rdoc index if requested RDOCTARGET="" AC_ARG_ENABLE(install-doc, diff --git a/gc.c b/gc.c index ab71d22..9ad716f 100644 --- a/gc.c +++ b/gc.c @@ -411,7 +411,6 @@ rb_gc_unregister_address(addr) } } -#undef GC_DEBUG void rb_global_variable(var) @@ -602,6 +601,85 @@ rb_gc_dump() return Qnil; } + +static char* obj_type(int tp); + +#ifdef GC_DEBUG +/* + * call-seq: + * GC.dump_file_and_line_info(String, boolean) => nil + * + * dumps information on which currently allocated object was created by which file and on which line + * + * GC.dump_file_and_line_info(String, boolean) #=> nil + * + * The second parameter specifies whether class names should be included in the dump. + * Note that including class names will allocate additional string objects on the heap. + * + */ + +VALUE +rb_gc_dump_file_and_line_info(int argc, VALUE *argv) +{ + VALUE filename, str, include_classnames = Qnil; + char *fname = NULL; + char *klass = NULL; + FILE* f = NULL; + int i,n = 0; + + rb_scan_args(argc, argv, "11", &filename, &include_classnames); + + str = StringValue(filename); + fname = RSTRING(str)->ptr; + f = fopen(fname, "w"); + + for (i = 0; i < heaps_used; i++) { + RVALUE *p, *pend; + + p = heaps[i].slot; pend = p + heaps[i].limit; + for (;p < pend; p++) { + if (p->as.basic.flags) { + fprintf(f, "%s:%s:%d", obj_type(p->as.basic.flags & T_MASK), p->file, p->line); + // rb_obj_classname will create objects on the heap, we need a better solution + if (include_classnames == Qtrue) { + /* write the class */ + fprintf(f, ":"); + switch (TYPE(p)) { + case T_NONE: + fprintf(f, "__none__"); + break; + case T_BLKTAG: + fprintf(f, "__blktag__"); + break; + case T_UNDEF: + fprintf(f, "__undef__"); + break; + case T_VARMAP: + fprintf(f, "__varmap__"); + break; + case T_SCOPE: + fprintf(f, "__scope__"); + break; + case T_NODE: + fprintf(f, "__node__"); + break; + default: + if (!p->as.basic.klass) { + fprintf(f, "__unknown__"); + } else { + fprintf(f, rb_obj_classname((VALUE)p)); + } + } + } + fprintf(f, "\n"); + } + } + } + fclose(f); + return Qnil; +} +#endif + /* * call-seq: * GC.log String => String @@ -1066,6 +1144,11 @@ gc_mark(ptr, lev) if (obj->as.basic.flags & FL_MARK) return; /* already marked */ obj->as.basic.flags |= FL_MARK; +#ifdef GC_DEBUG + /* mark our new reference point for sourcefile objects */ + mark_source_filename(RANY(obj)->file); +#endif + if (lev > GC_LEVEL_MAX || (lev == 0 && ruby_stack_check())) { if (!mark_stack_overflow) { if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) { @@ -1104,6 +1187,11 @@ gc_mark_children(ptr, lev) if (obj->as.basic.flags & FL_MARK) return; /* already marked */ obj->as.basic.flags |= FL_MARK; +#ifdef GC_DEBUG + /* mark our new reference point for sourcefile objects */ + mark_source_filename(RANY(obj)->file); +#endif + marking: if (FL_TEST(obj, FL_EXIVAR)) { rb_mark_generic_ivar(ptr); @@ -1550,6 +1638,7 @@ gc_sweep() live_counts[i], free_counts[i], obj_type(i)); } } + fflush(gc_data_file); } /* clear finalization list */ @@ -2526,6 +2615,9 @@ Init_GC() rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, +#ifdef GC_DEBUG + rb_define_singleton_method(rb_mGC, +#endif rb_define_singleton_method(rb_mGC, "collections", rb_gc_collections, 0); "time", rb_gc_time, 0); "dump", rb_gc_dump, 0); "dump_file_and_line_info", rb_gc_dump_file_and_line_info, -1); "log", rb_gc_log, 1); rb_mObSpace = rb_define_module("ObjectSpace"); 1.26.5.1.12.1.15. 05-display-full-stack-trace.patch diff --git a/eval.c b/eval.c index 00bcd36..5ee11a0 100644 --- a/eval.c +++ b/eval.c @@ -1325,8 +1325,8 @@ error_print() int truncate = eclass == rb_eSysStackError; #define -#define -#define +#define +#define TRACE_MAX (TRACE_HEAD+TRACE_TAIL+5) TRACE_HEAD 8 TRACE_TAIL 5 TRACE_HEAD 100 TRACE_TAIL 100 ep = RARRAY(errat); for (i=1; i<ep->len; i++) { 1.26.5.1.12.1.16. 06-better-source-file-tracing.patch diff --git a/eval.c b/eval.c index 5ee11a0..8a2f492 100644 --- a/eval.c +++ b/eval.c @@ -1161,7 +1161,7 @@ static VALUE trace_func = 0; static int tracing = 0; static void call_trace_func _((rb_event_t,NODE*,VALUE,ID,VALUE)); -#if 0 +#if 1 #define SET_CURRENT_SOURCE() (ruby_sourcefile = ruby_current_node->nd_file, \ ruby_sourceline = nd_line(ruby_current_node)) #else 1.26.5.1.12.1.17. 13-heap-slot-size.patch diff --git a/gc.c b/gc.c index 7db1ef6..57740d2 100644 --- a/gc.c +++ b/gc.c @@ -2891,6 +2891,7 @@ Init_GC() rb_define_singleton_method(rb_mGC, "allocated_size", rb_gc_allocated_size, 0); rb_define_singleton_method(rb_mGC, "num_allocations", rb_gc_num_allocations, 0); rb_define_singleton_method(rb_mGC, "heap_slots", rb_gc_heap_slots, 0); + rb_define_const(rb_mGC, "HEAP_SLOT_SIZE", INT2FIX(sizeof(RVALUE))); rb_define_singleton_method(rb_mGC, "collections", rb_gc_collections, 0); rb_define_singleton_method(rb_mGC, "time", rb_gc_time, 0); rb_define_singleton_method(rb_mGC, "dump", rb_gc_dump, 0); 1.26.5.1.13. head 1.26.5.1.13.1. railsexpress 1.26.5.1.13.1.1. 09-track-malloc-size.patch diff --git a/gc.c b/gc.c index a3cbe91..30a1219 100644 --- a/gc.c +++ b/gc.c @@ -79,6 +79,17 @@ void *alloca (); static unsigned long malloc_increase = 0; static unsigned long malloc_limit = GC_MALLOC_LIMIT; + +#ifdef HAVE_LONG_LONG +static unsigned LONG_LONG gc_allocated_size = 0; +static unsigned LONG_LONG gc_num_allocations = 0; +#else +static unsigned long gc_allocated_size = 0; +static unsigned long gc_num_allocations = 0; +#endif +static int gc_statistics = 0; + + static void run_final(); static VALUE nomem_error; static void garbage_collect(); @@ -163,6 +174,11 @@ ruby_xmalloc(size) } malloc_increase += size; + if (gc_statistics) { + gc_allocated_size += size; +gc_num_allocations += 1; + } + return mem; } @@ -220,7 +236,6 @@ ruby_xfree(x) extern int ruby_in_compile; static int dont_gc; -static int gc_statistics = 0; static GC_TIME_TYPE gc_time = 0; static int gc_collections = 0; static int verbose_gc_stats = Qfalse; @@ -329,11 +344,55 @@ rb_gc_clear_stats() { gc_collections = 0; gc_time = 0; + gc_allocated_size = 0; + gc_num_allocations = 0; return Qnil; } /* * call-seq: + * GC.allocated_size => Integer + * + * Returns the size of memory (in bytes) allocated since GC statistics collection + * was enabled. + * + * GC.allocated_size #=> 35 + * + */ +VALUE +rb_gc_allocated_size() +{ +#if HAVE_LONG_LONG + return ULL2NUM(gc_allocated_size); +#else + return ULONG2NUM(gc_allocated_size); +#endif +} + +/* + * call-seq: + * GC.num_allocations => Integer + * + * Returns the number of memory allocations since GC statistics collection + * was enabled. + * + * GC.num_allocations #=> 150 + * + */ +VALUE +rb_gc_num_allocations() +{ +#if HAVE_LONG_LONG + return ULL2NUM(gc_num_allocations); +#else + return ULONG2NUM(gc_num_allocations); +#endif +} + +/* + +/* + * call-seq: * GC.collections => Integer * * Returns the number of garbage collections performed while GC statistics collection @@ -2753,6 +2812,8 @@ Init_GC() rb_define_singleton_method(rb_mGC, "enable_stats", rb_gc_enable_stats, 0); rb_define_singleton_method(rb_mGC, "disable_stats", rb_gc_disable_stats, 0); rb_define_singleton_method(rb_mGC, "clear_stats", rb_gc_clear_stats, 0); + rb_define_singleton_method(rb_mGC, "allocated_size", rb_gc_allocated_size, 0); + rb_define_singleton_method(rb_mGC, "num_allocations", rb_gc_num_allocations, 0); rb_define_singleton_method(rb_mGC, "collections", rb_gc_collections, 0); rb_define_singleton_method(rb_mGC, "time", rb_gc_time, 0); rb_define_singleton_method(rb_mGC, "dump", rb_gc_dump, 0); diff --git a/intern.h b/intern.h index 99696f1..1117614 100644 --- a/intern.h +++ b/intern.h @@ -272,6 +272,8 @@ VALUE rb_gc_disable _((void)); VALUE rb_gc_start _((void)); void rb_gc_before_fork _((void)); void rb_gc_after_fork _((void)); +VALUE rb_gc_allocated_size _((void)); +VALUE rb_gc_num_allocations _((void)); /* hash.c */ void st_foreach_safe _((struct st_table *, int (*)(ANYARGS), unsigned long)); void rb_hash_foreach _((VALUE, int (*)(ANYARGS), VALUE)); 1.26.5.1.13.1.2. 16-add-object-size-information-to-heap-dump.patch diff --git a/gc.c b/gc.c index 0ce7e68..53450bf 100644 --- a/gc.c +++ b/gc.c @@ -953,9 +953,21 @@ rb_gc_dump_file_and_line_info(int argc, VALUE *argv) if (!p->as.basic.klass) { fprintf(f, "__unknown__"); } else { fprintf(f, rb_obj_classname((VALUE)p)); + fprintf(f, "%s", rb_obj_classname((VALUE)p)); } } + /* print object size for some known object types */ + switch (TYPE(p)) { + case T_STRING: + fprintf(f, ":%lu", RSTRING(p)->len); + break; + case T_ARRAY: + fprintf(f, ":%lu", RARRAY(p)->len); + break; + case T_HASH: + fprintf(f, ":%d", RHASH(p)->tbl->num_entries); + break; + } } fprintf(f, "\n"); } @@ -1924,10 +1936,10 @@ gc_sweep() heap_slots_live_after_last_gc = live; if (do_gc_stats) { fprintf(gc_data_file, "objects processed: %.7d\n", live+freed); fprintf(gc_data_file, "live objects : %.7d\n", live); fprintf(gc_data_file, "freelist objects : %.7d\n", freed - really_freed); fprintf(gc_data_file, "freed objects : %.7d\n", really_freed); fprintf(gc_data_file, "objects processed: %.7lu\n", live+freed); fprintf(gc_data_file, "live objects : %.7lu\n", live); fprintf(gc_data_file, "freelist objects : %.7lu\n", freed - really_freed); fprintf(gc_data_file, "freed objects : %.7lu\n", really_freed); for(i=0; i<256; i++) { if (free_counts[i]>0 || live_counts[i]>0) { fprintf(gc_data_file, @@ -2258,7 +2270,7 @@ garbage_collect() gc_time += musecs_used; + + + + if (verbose_gc_stats) { fprintf(gc_data_file, "GC time: %d msec\n", musecs_used / 1000); fprintf(gc_data_file, "GC time: %ld msec\n", (long)(musecs_used / 1000)); fflush(gc_data_file); } + } 1.26.5.1.13.1.3. 15-track-live-dataset-size.patch diff --git a/gc.c b/gc.c index 2c34932..0ce7e68 100644 --- a/gc.c +++ b/gc.c @@ -89,6 +89,7 @@ static unsigned long gc_num_allocations = 0; #endif static int gc_statistics = 0; +static unsigned long heap_slots_live_after_last_gc = 0; static void run_final(); static VALUE nomem_error; @@ -465,6 +466,23 @@ rb_gc_time() #endif } +/* + * call-seq: + * GC.heap_slots_live_after_last_gc => Integer + * + * Returns the number of heap slots which were live after the last garbage collection. + * + * GC.heap_slots_live_after_last_gc #=> 231223 + * + */ +VALUE +rb_gc_heap_slots_live_after_last_gc() +{ + return ULONG2NUM(heap_slots_live_after_last_gc); +} + + + VALUE rb_mGC; /* @@ -1903,6 +1921,7 @@ gc_sweep() } during_gc = 0; live_objects = live; + heap_slots_live_after_last_gc = live; if (do_gc_stats) { fprintf(gc_data_file, "objects processed: %.7d\n", live+freed); @@ -2924,6 +2943,7 @@ Init_GC() rb_define_singleton_method(rb_mGC, "allocated_size", rb_gc_allocated_size, 0); rb_define_singleton_method(rb_mGC, "num_allocations", rb_gc_num_allocations, 0); rb_define_singleton_method(rb_mGC, "heap_slots", rb_gc_heap_slots, 0); + rb_define_singleton_method(rb_mGC, "heap_slots_live_after_last_gc", rb_gc_heap_slots_live_after_last_gc, 0); rb_define_const(rb_mGC, "HEAP_SLOT_SIZE", INT2FIX(sizeof(RVALUE))); rb_define_singleton_method(rb_mGC, "collections", rb_gc_collections, 0); rb_define_singleton_method(rb_mGC, "time", rb_gc_time, 0); 1.26.5.1.13.1.4. 14-add-trace-stats-enabled-methods.patch diff --git a/gc.c b/gc.c index 57740d2..2c34932 100644 --- a/gc.c +++ b/gc.c @@ -350,6 +350,22 @@ rb_gc_disable_stats() /* * call-seq: + * GC.stats_enabled? => true or false + * + * Check whether GC stats have been enabled. + * + * GC.stats_enabled? #=> false or true + * + */ + +VALUE +rb_gc_stats_enabled() +{ + return gc_statistics ? Qtrue : Qfalse; +} + +/* + * call-seq: * GC.clear_stats => nil * * Clears garbage collection statistics, returning nil. This resets the number @@ -491,6 +507,22 @@ rb_gc_disable_trace() return old; } +/* + * call-seq: + * GC.trace_enabled? => true or false + * + * Check whether GC tracing has been enabled. + * + * GC.trace_enabled? #=> false or true + * + */ + +VALUE +rb_gc_trace_enabled() +{ + return verbose_gc_stats ? Qtrue : Qfalse; +} + char* GC_LOGFILE_IVAR = "@gc_logfile_name"; /* @@ -2887,6 +2919,7 @@ Init_GC() rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, + rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, @@ -2902,6 +2935,7 @@ Init_GC() rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, rb_define_singleton_method(rb_mGC, + rb_define_singleton_method(rb_mGC, "enable_stats", rb_gc_enable_stats, 0); "disable_stats", rb_gc_disable_stats, 0); "stats_enabled?", rb_gc_stats_enabled, 0); "clear_stats", rb_gc_clear_stats, 0); "allocated_size", rb_gc_allocated_size, 0); "num_allocations", rb_gc_num_allocations, 0); "log_file", rb_gc_log_file, -1); "enable_trace", rb_gc_enable_trace, 0); "disable_trace", rb_gc_disable_trace, 0); "trace_enabled?", rb_gc_trace_enabled, 0); rb_mObSpace = rb_define_module("ObjectSpace"); rb_define_module_function(rb_mObSpace, "each_object", os_each_obj, -1); 1.26.5.1.13.1.5. 02-fix-tests-for-osx.patch diff --git a/test/drb/drbtest.rb b/test/drb/drbtest.rb index bc16ab1..c12b168 100644 --- a/test/drb/drbtest.rb +++ b/test/drb/drbtest.rb @@ -22,7 +22,7 @@ class DRbService %w(ut_drb.rb ut_array.rb ut_port.rb ut_large.rb ut_safe1.rb ut_eval.rb).each do |nm| add_service_command(nm) end - @server = @@server = DRb::DRbServer.new('druby://localhost:0', @@manager, {}) + @server = @@server = DRb::DRbServer.new('druby://127.0.0.1:0', @@manager, {}) @@manager.uri = @@server.uri def self.manager @@manager @@ -79,16 +79,16 @@ module DRbCore end + + + + + + def test_00_DRbObject ro = DRbObject.new(nil, 'druby://localhost:12345') assert_equal('druby://localhost:12345', ro.__drburi) ro = DRbObject.new(nil, 'druby://127.0.0.1:12345') assert_equal('druby://127.0.0.1:12345', ro.__drburi) assert_equal(nil, ro.__drbref) ro = DRbObject.new_with_uri('druby://localhost:12345') assert_equal('druby://localhost:12345', ro.__drburi) ro = DRbObject.new_with_uri('druby://127.0.0.1:12345') assert_equal('druby://127.0.0.1:12345', ro.__drburi) assert_equal(nil, ro.__drbref) ro = DRbObject.new_with_uri('druby://localhost:12345?foobar') assert_equal('druby://localhost:12345', ro.__drburi) ro = DRbObject.new_with_uri('druby://127.0.0.1:12345?foobar') assert_equal('druby://127.0.0.1:12345', ro.__drburi) assert_equal(DRb::DRbURIOption.new('foobar'), ro.__drbref) end diff --git a/test/drb/ut_drb.rb b/test/drb/ut_drb.rb index f5720cf..265713d 100644 --- a/test/drb/ut_drb.rb +++ b/test/drb/ut_drb.rb @@ -154,7 +154,7 @@ if __FILE__ == $0 DRb::DRbServer.default_argc_limit(8) DRb::DRbServer.default_load_limit(4096) - DRb.start_service('druby://localhost:0', DRbEx.new) + DRb.start_service('druby://127.0.0.1:0', DRbEx.new) es = DRb::ExtServ.new(ARGV.shift, ARGV.shift) DRb.thread.join end diff --git a/test/drb/ut_drb_drbssl.rb b/test/drb/ut_drb_drbssl.rb index 0a2191e..bca3012 100644 --- a/test/drb/ut_drb_drbssl.rb +++ b/test/drb/ut_drb_drbssl.rb @@ -18,7 +18,7 @@ if __FILE__ == $0 DRb::DRbServer.default_argc_limit(8) DRb::DRbServer.default_load_limit(4096) - DRb.start_service('drbssl://localhost:0', DRbEx.new, config) + DRb.start_service('drbssl://127.0.0.1:0', DRbEx.new, config) es = DRb::ExtServ.new(ARGV.shift, ARGV.shift) DRb.thread.join end diff --git a/test/drb/ut_eval.rb b/test/drb/ut_eval.rb index 4df963e..9127939 100644 --- a/test/drb/ut_eval.rb +++ b/test/drb/ut_eval.rb @@ -3,7 +3,7 @@ require 'drb/extserv' class EvalAttack def initialize @four = DRb::DRbServer.new('druby://localhost:0', self, {:safe_level => 4}) + @four = DRb::DRbServer.new('druby://127.0.0.1:0', self, {:safe_level => 4}) end def four @@ -25,7 +25,7 @@ if __FILE__ == $0 $SAFE = 1 + DRb.start_service('druby://localhost:0', EvalAttack.new, {:safe_level => 2}) DRb.start_service('druby://127.0.0.1:0', EvalAttack.new, {:safe_level => 2}) es = DRb::ExtServ.new(ARGV.shift, ARGV.shift) DRb.thread.join end diff --git a/test/drb/ut_large.rb b/test/drb/ut_large.rb index d6717c5..0aefd1b 100644 --- a/test/drb/ut_large.rb +++ b/test/drb/ut_large.rb @@ -31,7 +31,7 @@ if __FILE__ == $0 DRb::DRbServer.default_argc_limit(3) DRb::DRbServer.default_load_limit(100000) DRb.start_service('druby://localhost:0', DRbLarge.new) DRb.start_service('druby://127.0.0.1:0', DRbLarge.new) es = DRb::ExtServ.new(ARGV.shift, ARGV.shift) DRb.thread.join end diff --git a/test/drb/ut_safe1.rb b/test/drb/ut_safe1.rb index 4df8e1e..ee097f6 100644 --- a/test/drb/ut_safe1.rb +++ b/test/drb/ut_safe1.rb @@ -8,7 +8,7 @@ if __FILE__ == $0 it end + + DRb.start_service('druby://localhost:0', [1, 2, 'III', 4, "five", 6], DRb.start_service('druby://127.0.0.1:0', [1, 2, 'III', 4, "five", 6], {:safe_level => 1}) es = DRb::ExtServ.new(ARGV.shift, ARGV.shift) DRb.thread.join diff --git a/test/net/pop/test_pop.rb b/test/net/pop/test_pop.rb index c8aa9a8..129ca08 100644 --- a/test/net/pop/test_pop.rb +++ b/test/net/pop/test_pop.rb @@ -3,10 +3,14 @@ require 'test/unit' require 'digest/md5' class TestPOP < Test::Unit::TestCase def localhost '127.0.0.1' end + + + + + def setup @users = {'user' => 'pass' } @ok_user = 'user' @stamp_base = "#{$$}.#{Time.now.to_i}@localhost" @stamp_base = "#{$$}.#{Time.now.to_i}@#{localhost}" end def test_pop_auth_ok @@ -64,7 +68,7 @@ class TestPOP < Test::Unit::TestCase end + def pop_test(apop=false) host = 'localhost' host = localhost server = TCPServer.new(host, 0) port = server.addr[1] thread = Thread.start do 1.26.5.1.13.1.6. 10-track-object-allocation.patch diff --git a/gc.c b/gc.c index 30a1219..5b42b90 100644 --- a/gc.c +++ b/gc.c @@ -96,6 +96,26 @@ static void garbage_collect(); int ruby_gc_stress = 0; +static unsigned long live_objects = 0; +unsigned long rb_os_live_objects() +{ + return live_objects; +} + +#if defined(HAVE_LONG_LONG) +static unsigned LONG_LONG allocated_objects = 0; +unsigned LONG_LONG rb_os_allocated_objects() +{ + return allocated_objects; +} +#else +static unsigned long allocated_objects = 0; +unsigned long rb_os_allocated_objects() +{ + return allocated_objects; +} +#endif + NORETURN(void rb_exc_jump _((VALUE))); void @@ -987,6 +1007,8 @@ rb_newobj() RANY(obj)->file = ruby_sourcefile; RANY(obj)->line = ruby_sourceline; #endif + live_objects++; + allocated_objects++; return obj; } @@ -1825,6 +1847,7 @@ gc_sweep() add_heap(); } during_gc = 0; + live_objects = live; if (do_gc_stats) { fprintf(gc_data_file, "objects processed: %.7d\n", live+freed); @@ -2790,6 +2813,35 @@ rb_obj_id(VALUE obj) return (VALUE)((long)obj|FIXNUM_FLAG); } +/* call-seq: + * ObjectSpace.live_objects => number + * + * Returns the count of objects currently allocated in the system. This goes + * down after the garbage collector runs. + */ +static +VALUE os_live_objects(VALUE self) +{ + return ULONG2NUM(live_objects); +} + +/* call-seq: + * ObjectSpace.allocated_objects => number + * + * Returns the count of objects allocated since the Ruby interpreter has + * started. This number can only increase. To know how many objects are + * currently allocated, use ObjectSpace::live_objects + */ +static +VALUE os_allocated_objects(VALUE self) +{ +#if defined(HAVE_LONG_LONG) + return ULL2NUM(allocated_objects); +#else + return ULONG2NUM(allocated_objects); +#endif +} + /* * The <code>GC</code> module provides an interface to Ruby's mark and * sweep garbage collection mechanism. Some of the underlying methods @@ -2833,6 +2885,9 @@ Init_GC() rb_define_module_function(rb_mObSpace, "finalizers", finals, 0); rb_define_module_function(rb_mObSpace, "call_finalizer", call_final, 1); + + + rb_define_module_function(rb_mObSpace, "live_objects", os_live_objects, 0); rb_define_module_function(rb_mObSpace, "allocated_objects", os_allocated_objects, 0); rb_define_module_function(rb_mObSpace, "define_finalizer", define_final, -1); rb_define_module_function(rb_mObSpace, "undefine_finalizer", undefine_final, 1); diff --git a/intern.h b/intern.h index 1117614..a87661d 100644 --- a/intern.h +++ b/intern.h @@ -274,6 +274,12 @@ void rb_gc_before_fork _((void)); void rb_gc_after_fork _((void)); VALUE rb_gc_allocated_size _((void)); VALUE rb_gc_num_allocations _((void)); +unsigned long rb_os_live_objects _((void)); +#ifdef HAVE_LONG_LONG +unsigned LONG_LONG rb_os_allocated_objects _((void)); +#else +unsigned long rb_os_allocated_objects _((void)); +#endif /* hash.c */ void st_foreach_safe _((struct st_table *, int (*)(ANYARGS), unsigned long)); void rb_hash_foreach _((VALUE, int (*)(ANYARGS), VALUE)); 1.26.5.1.13.1.7. 12-fix-heap-size-growth-logic.patch diff --git a/gc.c b/gc.c index 21b3f6b..7db1ef6 100644 --- a/gc.c +++ b/gc.c @@ -694,6 +694,7 @@ static int heap_size = 0; static static +static static int heap_free_min = 4096; int heap_slots_increment = 10000; int initial_heap_slots_increment = 10000; double heap_slots_growth_factor = 1.8; static long initial_malloc_limit = GC_MALLOC_LIMIT; @@ -771,14 +772,13 @@ static void set_gc_parameters() if (verbose_gc_stats) { fprintf(gc_data_file, "RUBY_HEAP_SLOTS_INCREMENT=%s\n", heap_slots_incr_ptr); } if (heap_slots_incr_i > 0) { heap_slots_increment = heap_slots_incr_i; } + heap_slots_increment = heap_slots_incr_i; + initial_heap_slots_increment = heap_slots_increment; } heap_slots_growth_factor_ptr = getenv("RUBY_HEAP_SLOTS_GROWTH_FACTOR"); if (heap_slots_growth_factor_ptr != NULL) { double heap_slots_growth_factor_d = atoi(heap_slots_growth_factor_ptr); + double heap_slots_growth_factor_d = atof(heap_slots_growth_factor_ptr); if (verbose_gc_stats) { fprintf(gc_data_file, "RUBY_HEAP_SLOTS_GROWTH_FACTOR=%s\n", heap_slots_growth_factor_ptr); } @@ -988,8 +988,13 @@ add_heap() if (lomem == 0 || lomem > p) lomem = p; if (himem < pend) himem = pend; heaps_used++; heap_slots += heap_slots_increment; heap_slots_increment *= heap_slots_growth_factor; + if (heaps_used == 1) + heap_slots = initial_heap_slots_increment; + else { + heap_slots_increment *= heap_slots_growth_factor; + heap_slots += heap_slots_increment; + } + if (heap_slots <= 0) heap_slots = heap_min_slots; while (p < pend) { @@ -1879,6 +1884,7 @@ gc_sweep() live_counts[i], free_counts[i], obj_type(i)); } } + rb_gc_dump(); fflush(gc_data_file); } 1.26.5.1.13.1.8. 01-ignore-generated-files.patch diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..00c347a --- /dev/null +++ b/.gitignore @@ -0,0 +1,95 @@ +.ext +.installed.list +.rbconfig.time +Makefile +autom4te.cache/ +config.h +config.status +configure +ext/Win32API/Makefile +ext/bigdecimal/Makefile +ext/curses/Makefile +ext/dbm/Makefile +ext/digest/Makefile +ext/digest/bubblebabble/Makefile +ext/digest/md5/Makefile +ext/digest/rmd160/Makefile +ext/digest/sha1/Makefile +ext/digest/sha2/Makefile +ext/dl/Makefile +ext/dl/call.func +ext/dl/callback.func +ext/dl/cbtable.func +ext/dl/dlconfig.h +ext/dl/dlconfig.rb +ext/enumerator/Makefile +ext/etc/Makefile +ext/fcntl/Makefile +ext/gdbm/Makefile +ext/iconv/Makefile +ext/io/wait/Makefile +ext/nkf/Makefile +ext/openssl/Makefile +ext/openssl/extconf.h +ext/pty/Makefile +ext/racc/cparse/Makefile +ext/readline/Makefile +ext/sdbm/Makefile +ext/socket/Makefile +ext/stringio/Makefile +ext/strscan/Makefile +ext/syck/Makefile +ext/syslog/Makefile +ext/thread/Makefile +ext/tk/Makefile +ext/tk/tkutil/Makefile +ext/win32ole/Makefile +ext/win32ole/.document +ext/zlib/Makefile +largefile.h +miniruby +parse.c +rbconfig.rb +ruby +enc.mk +ext/bigdecimal/extconf.h +ext/continuation/ +ext/coverage/ +ext/curses/extconf.h +ext/dbm/extconf.h +ext/digest/bubblebabble/extconf.h +ext/digest/extconf.h +ext/digest/md5/extconf.h +ext/digest/rmd160/extconf.h +ext/digest/sha1/extconf.h +ext/digest/sha2/extconf.h +ext/dl/callback.h +ext/dl/extconf.h +ext/etc/extconf.h +ext/fcntl/extconf.h +ext/fiber/ +ext/iconv/extconf.h +ext/io/wait/extconf.h +ext/json/ +ext/nkf/extconf.h +ext/pty/extconf.h +ext/racc/cparse/extconf.h +ext/readline/extconf.h +ext/ripper/ +ext/sdbm/extconf.h +ext/socket/constants.h +ext/socket/extconf.h +ext/stringio/extconf.h +ext/strscan/extconf.h +ext/syck/extconf.h +ext/syslog/extconf.h +ext/tk/extconf.h +ext/tk/tkutil/extconf.h +ext/zlib/extconf.h +miniprelude.c +prelude.c +revision.h +*.dylib +*.log +*.dSYM +patches-ruby* 1.26.5.1.13.1.9. 04-railsbench-gc-patch.patch diff --git a/gc.c b/gc.c index fa45cd1..ab71d22 100644 --- a/gc.c +++ b/gc.c @@ -22,8 +22,16 @@ #include <setjmp.h> #include <sys/types.h> +#ifdef _WIN32 +#include <string.h> +#else +#include <strings.h> +#endif + #ifdef HAVE_SYS_TIME_H #include <sys/time.h> +#elif defined(_WIN32) +#include <time.h> #endif #ifdef HAVE_SYS_RESOURCE_H @@ -42,7 +50,6 @@ void rb_io_fptr_finalize _((struct rb_io_t*)); #ifdef __CYGWIN__ int _setjmp(), _longjmp(); #endif /* Make alloca work the best possible way. */ #ifdef __GNUC__ # ifndef atarist @@ -86,12 +93,12 @@ rb_memerror() rb_thread_t th = rb_curr_thread; if (!nomem_error || -(rb_thread_raised_p(th, RAISED_NOMEMORY) && rb_safe_level() < 4)) { -fprintf(stderr, "[FATAL] failed to allocate memory\n"); -exit(1); + (rb_thread_raised_p(th, RAISED_NOMEMORY) && rb_safe_level() < 4)) { + fprintf(stderr, "[FATAL] failed to allocate memory\n"); + exit(1); } if (rb_thread_raised_p(th, RAISED_NOMEMORY)) { -rb_exc_jump(nomem_error); + rb_exc_jump(nomem_error); } rb_thread_raised_set(th, RAISED_NOMEMORY); rb_exc_raise(nomem_error); @@ -139,7 +146,7 @@ ruby_xmalloc(size) void *mem; if (size < 0) { -rb_raise(rb_eNoMemError, "negative allocation size (or too big)"); + rb_raise(rb_eNoMemError, "negative allocation size (or too big)"); } if (size == 0) size = 1; @@ -148,11 +155,11 @@ ruby_xmalloc(size) } RUBY_CRITICAL(mem = malloc(size)); if (!mem) { -garbage_collect(); -RUBY_CRITICAL(mem = malloc(size)); -if (!mem) { rb_memerror(); -} + garbage_collect(); + RUBY_CRITICAL(mem = malloc(size)); + if (!mem) { + rb_memerror(); + } } malloc_increase += size; @@ -179,17 +186,17 @@ ruby_xrealloc(ptr, size) void *mem; if (size < 0) { -rb_raise(rb_eArgError, "negative re-allocation size"); + rb_raise(rb_eArgError, "negative re-allocation size"); } if (!ptr) return xmalloc(size); if (size == 0) size = 1; if (ruby_gc_stress) garbage_collect(); RUBY_CRITICAL(mem = realloc(ptr, size)); if (!mem) { -garbage_collect(); -RUBY_CRITICAL(mem = realloc(ptr, size)); -if (!mem) { rb_memerror(); + garbage_collect(); + RUBY_CRITICAL(mem = realloc(ptr, size)); + if (!mem) { + rb_memerror(); } } malloc_increase += size; @@ -202,11 +209,20 @@ ruby_xfree(x) void *x; { if (x) -RUBY_CRITICAL(free(x)); + RUBY_CRITICAL(free(x)); } +#if HAVE_LONG_LONG +#define GC_TIME_TYPE LONG_LONG +#else +#define GC_TIME_TYPE long +#endif + extern int ruby_in_compile; static int dont_gc; +static int gc_statistics = 0; +static GC_TIME_TYPE gc_time = 0; +static int gc_collections = 0; static int during_gc; static int need_call_final = 0; static st_table *finalizer_table = 0; @@ -241,7 +257,7 @@ rb_gc_enable() * Disables garbage collection, returning <code>true</code> if garbage * collection was already disabled. * - * GC.disable #=> false + * GC.disable #=> false or true * GC.disable #=> true * */ @@ -255,6 +271,104 @@ rb_gc_disable() return old; } +/* + * call-seq: + * GC.enable_stats => true or false + * + * Enables garbage collection statistics, returning <code>true</code> if garbage + * collection statistics was already enabled. + * + * GC.enable_stats #=> false or true + * GC.enable_stats #=> true + * + */ + +VALUE +rb_gc_enable_stats() +{ + int old = gc_statistics; + gc_statistics = Qtrue; + return old; +} + +/* + * call-seq: + * GC.disable_stats => true or false + * + * Disables garbage collection statistics, returning <code>true</code> if garbage + * collection statistics was already disabled. + * + * GC.disable_stats #=> false or true + * GC.disable_stats #=> true + * + */ + +VALUE +rb_gc_disable_stats() +{ + int old = gc_statistics; + gc_statistics = Qfalse; + return old; +} + +/* + * call-seq: + * GC.clear_stats => nil + * + * Clears garbage collection statistics, returning nil. This resets the number + * of collections (GC.collections) and the time used (GC.time) to 0. + * + * GC.clear_stats #=> nil + * + */ + +VALUE +rb_gc_clear_stats() +{ + gc_collections = 0; + gc_time = 0; + return Qnil; +} + +/* + * call-seq: + * GC.collections => Integer + * + * Returns the number of garbage collections performed while GC statistics collection + * was enabled. + * + * GC.collections #=> 35 + * + */ + +VALUE +rb_gc_collections() +{ + return INT2NUM(gc_collections); +} + +/* + * call-seq: + * GC.time => Integer + * + * Returns the time spent during garbage collection while GC statistics collection + * was enabled (in micro seconds). + * + * GC.time #=> 20000 + * + */ + +VALUE +rb_gc_time() +{ +#if HAVE_LONG_LONG + return LL2NUM(gc_time); +#else + return LONG2NUM(gc_time); +#endif +} + + VALUE rb_mGC; static struct gc_list { @@ -281,19 +395,19 @@ rb_gc_unregister_address(addr) struct gc_list *tmp = global_List; if (tmp->varptr == addr) { -global_List = tmp->next; -RUBY_CRITICAL(free(tmp)); -return; + global_List = tmp->next; + RUBY_CRITICAL(free(tmp)); + return; } while (tmp->next) { -if (tmp->next->varptr == addr) { struct gc_list *t = tmp->next; + if (tmp->next->varptr == addr) { + struct gc_list *t = tmp->next; -} -tmp + + + + + tmp->next = tmp->next->next; RUBY_CRITICAL(free(t)); break; = tmp->next; tmp->next = tmp->next->next; RUBY_CRITICAL(free(t)); break; } tmp = tmp->next; } } @@ -312,26 +426,26 @@ rb_global_variable(var) typedef struct RVALUE { union { -struct { unsigned long flags;/* always 0 for freed obj */ struct RVALUE *next; -} free; -struct RBasic basic; -struct RObject object; -struct RClass klass; -struct RFloat flonum; -struct RString string; -struct RArray array; -struct RRegexp regexp; -struct RHash hash; -struct RData data; -struct RStruct rstruct; -struct RBignum bignum; -struct RFile file; -struct RNode node; -struct RMatch match; -struct RVarmap varmap; -struct SCOPE scope; + struct { + unsigned long flags; /* always 0 for freed obj */ + struct RVALUE *next; + } free; + struct RBasic basic; + struct RObject object; + struct RClass klass; + struct RFloat flonum; + struct RString string; + struct RArray array; + struct RRegexp regexp; + struct RHash hash; + struct RData data; + struct RStruct rstruct; + struct RBignum bignum; + struct RFile file; + struct RNode node; + struct RMatch match; + struct RVarmap varmap; + struct SCOPE scope; } as; #ifdef GC_DEBUG char *file; @@ -346,7 +460,7 @@ typedef struct RVALUE { static RVALUE *freelist = 0; static RVALUE *deferred_final_list = 0; -#define HEAPS_INCREMENT 10 +static int heaps_increment = 10; static struct heaps_slot { void *membase; RVALUE *slot; @@ -355,45 +469,197 @@ static struct heaps_slot { static int heaps_length = 0; static int heaps_used = 0; -#define HEAP_MIN_SLOTS 10000 -static int heap_slots = HEAP_MIN_SLOTS; +static int heap_min_slots = 10000; +static int heap_slots = 10000; -#define FREE_MIN 4096 +static int heap_free_min = 4096; +static int heap_slots_increment = 10000; +static double heap_slots_growth_factor = 1.8; + +static long initial_malloc_limit = GC_MALLOC_LIMIT; + +static int verbose_gc_stats = Qfalse; + +static FILE* gc_data_file = NULL; static RVALUE *himem, *lomem; +static void set_gc_parameters() +{ + char *gc_stats_ptr, *min_slots_ptr, *free_min_ptr, *heap_slots_incr_ptr, + *heap_incr_ptr, *malloc_limit_ptr, *gc_heap_file_ptr, *heap_slots_growth_factor_ptr; + + gc_data_file = stderr; + + gc_stats_ptr = getenv("RUBY_GC_STATS"); + if (gc_stats_ptr != NULL) { + int gc_stats_i = atoi(gc_stats_ptr); + if (gc_stats_i > 0) { + verbose_gc_stats = Qtrue; + } + } + + gc_heap_file_ptr = getenv("RUBY_GC_DATA_FILE"); + if (gc_heap_file_ptr != NULL) { + FILE* data_file = fopen(gc_heap_file_ptr, "w"); + if (data_file != NULL) { + gc_data_file = data_file; + } + else { + fprintf(stderr, + "can't open gc log file %s for writing, using default\n", gc_heap_file_ptr); + } + } + + min_slots_ptr = getenv("RUBY_HEAP_MIN_SLOTS"); + if (min_slots_ptr != NULL) { + int min_slots_i = atoi(min_slots_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_MIN_SLOTS=%s\n", min_slots_ptr); + } + if (min_slots_i > 0) { + heap_slots = min_slots_i; + heap_min_slots = min_slots_i; + } + } + + free_min_ptr = getenv("RUBY_HEAP_FREE_MIN"); + if (free_min_ptr != NULL) { + int free_min_i = atoi(free_min_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_FREE_MIN=%s\n", free_min_ptr); + } + if (free_min_i > 0) { + heap_free_min = free_min_i; + } + } + + heap_incr_ptr = getenv("RUBY_HEAP_INCREMENT"); + if (heap_incr_ptr != NULL) { + int heap_incr_i = atoi(heap_incr_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_INCREMENT=%s\n", heap_incr_ptr); + } + if (heap_incr_i > 0) { + heaps_increment = heap_incr_i; + } + } + + heap_slots_incr_ptr = getenv("RUBY_HEAP_SLOTS_INCREMENT"); + if (heap_slots_incr_ptr != NULL) { + int heap_slots_incr_i = atoi(heap_slots_incr_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_SLOTS_INCREMENT=%s\n", heap_slots_incr_ptr); + } + if (heap_slots_incr_i > 0) { + heap_slots_increment = heap_slots_incr_i; + } + } + + heap_slots_growth_factor_ptr = getenv("RUBY_HEAP_SLOTS_GROWTH_FACTOR"); + if (heap_slots_growth_factor_ptr != NULL) { + double heap_slots_growth_factor_d = atoi(heap_slots_growth_factor_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_HEAP_SLOTS_GROWTH_FACTOR=%s\n", heap_slots_growth_factor_ptr); + } + if (heap_slots_growth_factor_d > 0) { + heap_slots_growth_factor = heap_slots_growth_factor_d; + } + } + + malloc_limit_ptr = getenv("RUBY_GC_MALLOC_LIMIT"); + if (malloc_limit_ptr != NULL) { + int malloc_limit_i = atol(malloc_limit_ptr); + if (verbose_gc_stats) { + fprintf(gc_data_file, "RUBY_GC_MALLOC_LIMIT=%s\n", malloc_limit_ptr); + } + if (malloc_limit_i > 0) { + initial_malloc_limit = malloc_limit_i; + } + } +} + +/* + * call-seq: + * GC.dump => nil + * + * dumps information about the current GC data structures to the GC log file + * + * GC.dump #=> nil + * + */ + +VALUE +rb_gc_dump() +{ + int i; + + for (i = 0; i < heaps_used; i++) { + int heap_size = heaps[i].limit; + fprintf(gc_data_file, "HEAP[%2d]: size=%7d\n", i, heap_size); + } + + return Qnil; +} + +/* + * call-seq: + * GC.log String => String + * + * Logs string to the GC data file and returns it. + * + * GC.log "manual GC call" #=> "manual GC call" + * + */ + +VALUE +rb_gc_log(self, original_str) + VALUE self, original_str; +{ + if (original_str == Qnil) { + fprintf(gc_data_file, "\n"); + } + else { + VALUE str = StringValue(original_str); + char *p = RSTRING(str)->ptr; + fprintf(gc_data_file, "%s\n", p); + } + return original_str; +} + + static void add_heap() { RVALUE *p, *pend; if (heaps_used == heaps_length) { -/* Realloc heaps */ -struct heaps_slot *p; -int length; -heaps_length += HEAPS_INCREMENT; -length = heaps_length*sizeof(struct heaps_slot); -RUBY_CRITICAL( if (heaps_used > 0) { -p = (struct heaps_slot *)realloc(heaps, length); -if (p) heaps = p; } else { -p = heaps = (struct heaps_slot *)malloc(length); }); -if (p == 0) rb_memerror(); + /* Realloc heaps */ + struct heaps_slot *p; + int length; + + heaps_length += heaps_increment; + length = heaps_length*sizeof(struct heaps_slot); + RUBY_CRITICAL( + if (heaps_used > 0) { + p = (struct heaps_slot *)realloc(heaps, length); + if (p) heaps = p; + } + else { + p = heaps = (struct heaps_slot *)malloc(length); + }); + if (p == 0) rb_memerror(); } for (;;) { -RUBY_CRITICAL(p = (RVALUE*)malloc(sizeof(RVALUE)*(heap_slots+1))); -if (p == 0) { if (heap_slots == HEAP_MIN_SLOTS) { -rb_memerror(); } heap_slots = HEAP_MIN_SLOTS; continue; -} + RUBY_CRITICAL(p = (RVALUE*)malloc(sizeof(RVALUE)*(heap_slots+1))); + if (p == 0) { + if (heap_slots == heap_min_slots) { + rb_memerror(); + } + heap_slots = heap_min_slots; + continue; + } heaps[heaps_used].membase = p; if ((VALUE)p % sizeof(RVALUE) == 0) heap_slots += 1; @@ -401,25 +667,26 @@ add_heap() p = (RVALUE*)((VALUE)p + sizeof(RVALUE) - ((VALUE)p % sizeof(RVALUE))); heaps[heaps_used].slot = p; heaps[heaps_used].limit = heap_slots; -break; + break; } pend = p + heap_slots; if (lomem == 0 || lomem > p) lomem = p; if (himem < pend) himem = pend; heaps_used++; heap_slots *= 1.8; if (heap_slots <= 0) heap_slots = HEAP_MIN_SLOTS; + heap_slots += heap_slots_increment; + heap_slots_increment *= heap_slots_growth_factor; + if (heap_slots <= 0) heap_slots = heap_min_slots; while (p < pend) { -p->as.free.flags = 0; -p->as.free.next = freelist; -freelist = p; -p++; + p->as.free.flags = 0; + p->as.free.next = freelist; + freelist = p; + p++; } } #define RANY(o) ((RVALUE*)(o)) -int +int rb_during_gc() { return during_gc; @@ -431,7 +698,7 @@ rb_newobj() VALUE obj; if (during_gc) -rb_bug("object allocation during garbage collection phase"); + rb_bug("object allocation during garbage collection phase"); if (ruby_gc_stress || !freelist) garbage_collect(); @@ -580,13 +847,13 @@ rb_source_filename(f) st_data_t name; if (!st_lookup(source_filenames, (st_data_t)f, &name)) { -long len = strlen(f) + 1; -char *ptr = ALLOC_N(char, len + 1); -name = (st_data_t)ptr; -*ptr++ = 0; -MEMCPY(ptr, f, char, len); -st_add_direct(source_filenames, (st_data_t)ptr, name); -return ptr; + long len = strlen(f) + 1; + char *ptr = ALLOC_N(char, len + 1); + name = (st_data_t)ptr; + *ptr++ = 0; + MEMCPY(ptr, f, char, len); + st_add_direct(source_filenames, (st_data_t)ptr, name); + return ptr; } return (char *)name + 1; } @@ -596,7 +863,7 @@ mark_source_filename(f) char *f; { if (f) { -f[-1] = 1; + f[-1] = 1; } } @@ -605,12 +872,12 @@ sweep_source_filename(key, value) char *key, *value; { if (*value) { -*value = 0; -return ST_CONTINUE; + *value = 0; + return ST_CONTINUE; } else { -free(value); -return ST_DELETE; + free(value); + return ST_DELETE; } } @@ -625,14 +892,14 @@ gc_mark_all() init_mark_stack(); for (i = 0; i < heaps_used; i++) { -p = heaps[i].slot; pend = p + heaps[i].limit; -while (p < pend) { if ((p->as.basic.flags & FL_MARK) && -(p->as.basic.flags != FL_MARK)) { -gc_mark_children((VALUE)p, 0); } p++; -} + p = heaps[i].slot; pend = p + heaps[i].limit; + while (p < pend) { + if ((p->as.basic.flags & FL_MARK) && + (p->as.basic.flags != FL_MARK)) { + gc_mark_children((VALUE)p, 0); + } + p++; + } } } @@ -647,8 +914,8 @@ gc_mark_rest() init_mark_stack(); while(p != tmp_arry){ -p--; -gc_mark_children(*p, 0); + + p--; gc_mark_children(*p, 0); } } @@ -665,9 +932,9 @@ is_pointer_to_heap(ptr) /* check if p looks like a pointer */ for (i=0; i < heaps_used; i++) { -heap_org = heaps[i].slot; -if (heap_org <= p && p < heap_org + heaps[i].limit) return Qtrue; + heap_org = heaps[i].slot; + if (heap_org <= p && p < heap_org + heaps[i].limit) + return Qtrue; } return Qfalse; } @@ -680,10 +947,10 @@ mark_locations_array(x, n) VALUE v; while (n--) { v = *x; -if (is_pointer_to_heap((void *)v)) { gc_mark(v, 0); -} -x++; + if (is_pointer_to_heap((void *)v)) { + gc_mark(v, 0); + } + x++; } } @@ -780,7 +1047,7 @@ rb_gc_mark_maybe(obj) VALUE obj; { if (is_pointer_to_heap((void *)obj)) { -gc_mark(obj, 0); + gc_mark(obj, 0); } } @@ -828,7 +1095,7 @@ gc_mark_children(ptr, lev) { register RVALUE *obj = RANY(ptr); + goto marking;/* skip */ goto marking; /* skip */ again: obj = RANY(ptr); @@ -839,148 +1106,148 @@ gc_mark_children(ptr, lev) marking: if (FL_TEST(obj, FL_EXIVAR)) { -rb_mark_generic_ivar(ptr); + rb_mark_generi