error Your Ruby version is 2.6.8, but your Gemfile specified 2.7.5 - ruby

This happens when I run npx react-native init AwesomeProject.
When I check the system ruby version with ruby -v, it is already 2.7.5. ruby 2.7.5p203 (2021-11-24 revision f69aeb8314) [x86_64-darwin21]. Anyone has any idea for this problem?

Sounds like you’re using rvm to manage Ruby versions.
You need to install and run the correct version, not delete the current.
Something like
rvm install 2.7.5
rvm use 2.7.5

The Gemfile Isn't (Directly) Your Issue
The Gemfile is irrelevant to solving this issue. It's just triggering it because your in-project Ruby version isn't matching what RubyGems (via the Gemfile or Gemfile.lock) expects as a constraint. It could be a minimum version, an exact version, an approximate version, and so forth. There are a lot of ways to specify version constraints in a project, and the Gemfile is just where the constraint-related exception is being raised by Bundler.
You could possibly make the problem go away simply by removing the requirement for a later version of Ruby from the Gemfile or gemspec, removing the Gemfile.lock, and re-running Bundler. However, if your code relies on features in a later version this will just create other problems for you. You really ought to uncover what's changing your Ruby environment within the project directory.
Dotfiles
There are a lot of reasons this could happen, but if your system Ruby is 2.7.5, then you need to check your project directory for various dotfiles like:
.ruby-version
.rvmrc
~/.rvmrc
.envrc
.env
or various other files that affect your shell environment or whatever Ruby version manager you're using. Most Ruby version managers respect .ruby-version, but some version managers use other files, including defaults or shims that may be set elsewhere. IDE's also often have their own project-specific configuration files, too, and they can sometimes be set to override the project's standard settings.
Also, make sure to check your Gemfile.lock and *.gemspec in addition to the Gemfile itself, in case something is being specified there or constrained by some other dependency.
Inspecting Environment Variables
You should also look at the Ruby- and RubyGems-related environment variables from your project directory to see how various values are set within the project. For example:
printenv | grep -E '^(RUBY|GEM)' | sort
Shebang Lines
In addition, you should check your shebang lines in any executable Ruby or shell scripts you're relying on to see whether a specific non-system Ruby is being invoked. For example:
grep -Enr '^#.*ruby' *.rb | grep -F '.rb:1:'
will find all the shebang lines that properly appear on the first line of a Ruby file. This will either point to a specific Ruby like #!/usr/bin/ruby or might be using a PATH lookup with #!/usr/bin/env ruby.
Shell scripts might be harder to inspect, as there may be calls to other executables or even an exec command, so you'll need to be more liberal with your grepping if you are looking for an interpreter call further down than the shebang line.
Checking PATH Order
In the case of #!/usr/bin/env ruby, you should inspect your PATH environment variable to see why the Ruby you want isn't being called first. Using which -a ruby (if supported by your OS) will show you all rubies in your PATH in the order they would be invoked by the shell. It's possible that you're simply calling an unexpected Ruby version that comes first in the PATH.

Related

If a project's Ruby version is explicitly specified, could changing from RVM to rbenv introduce bugs?

I'm trying to figure out if it's possible that a bug I'm experiencing could be related to the fact that I use rbenv but the rest of my team uses RVM.
What I've been trying to figure out is whether the executables created by rbenv/RVM for a specific Ruby are the same. If the Ruby version and gem versions are explicitly specified in the .ruby_version and Gemfile respectively, is it possible that rbenv and RVM interpret code differently or should I expect identical outcomes?
UPDATE. A description of the actual bug I'm experiencing was requested, so here it is.
Essentially, the project is using the dotenv gem (and dotenv-rails) to read a .env file in the root directory. Two of the values (a salt and an IV) are Base64 encoded strings that contain newline characters. At some point in the decoding process, an extra backslash is being added before each newline character, causing the decryption to fail. The problem is, the dotenv gem appears to be reading the file correctly (i.e. running Dotenv.load in Rails console shows the strings parsed correctly), so it's some other gem or extension deeper in the stack causing the problem. And we have yet to identify it.
Our quick fix was to gsub the doubly escaped newlines (similar to this foreman bug fix, but some members of the team don't want to merge it because they're convinced it's an environment problem caused by rbenv. I don't think this is the case, but am wondering if it's a possibility before I try uninstalling rbenv and switching to RVM, which I really don't want to do.
UPDATE #2. Problem solved!
I did end up switching to RVM, but to no avail. However it did end up being an environment issue.
It was because my default shell is zsh but most of my team uses bash, and we were using heroku local:run to spin up the local dev environment. heroku local:run, it turns out, uses your default shell environment. Even if you make the call from a different shell (such as bash). However both rails console and heroku local:run rails console use sh by default. And zsh was handling the import of the env vars differently than bash and sh.
No, the binaries compiled by rvm and rbenv are not the same, and they are not drop-in compatible. (e.g., you cannot compile ruby with rvm and then drop it into an existing rbenv setup) The compilation options provided to each are different, and the resulting files are handled differently.
That said, you should consider two ruby binaries of the same version that were compiled with the same options to be binary-compatible; that is, any Ruby code that runs through one binary should run the same way through the other binary, regardless of what platform they were compiled on, provided they were compiled with the same options and libraries.
For example, if rvm is compiled without OpenSSL support you will have no end of trouble when trying to use libraries that rely on cryptographic functions. Likewise with bad versions of readline.
You can conduct a very simple experiment to determine the problem: compile ruby with both on the same computer and run your experiment through both versions.
For the specific problem you have outlined (dotenv and extra linebreaks), pay attention to the difference between single quoted and double quoted strings, and how Ruby handles control characters in them. Ruby interprets escape sequences in double quoted strings only, so you can likely resolve your issue by ensuring your value is always single quoted.

Change gem env RUBY EXECUTABLE path for one command

I would like to run gem commands, such as gem install, with a different ruby version than what is listed in gem env. The Ruby version I want to use is a pre-compiled version which I have the path for, so installing and using another version from RVM or similar would not solve my problem.
I do not want to change the RUBY EXECUTABLE permanently, just for one command at a time. I have tried to set GEM_HOME, GEM_PATH, PATH, RUBY and more. I have tried firing up gem with specific/version/of/ruby/path/ruby path/to/gem env, but I still get the default Ruby in my RUBY EXECUTABLE variable.
I even tried settingRUBY_EXECUTABLE=/path/to/correct/ruby, which also did not work.
What really surprised me was that when I edited the shebang in the path/to/gem file itself so it pointed to the correct Ruby, it still did not work! What is up with that?!
How can I change this variable so I can use gem goodness with my custom compiled Ruby?
This one is really beating me. I have now updated my rbconfig.rb to point to the desired Ruby path. I have looked at the rubygems source and replaced every single instance of the default ruby , in all the files I could find, with the path to the one I want. Even this did not set the environment correctly. Is this somehow hard-coded into the compiled ruby? If that is the case, why the star*4 is this done?
Try using rbenv (https://github.com/sstephenson/rbenv) or RVM to manage Ruby versions (https://rvm.io/). When you switch Ruby versions with rbenv, gem env will use use the new Ruby version. The following command can be used to change the Ruby version for a single shell:
$ rbenv shell 2.1.2
After hours and hours of research, stepping through the Ruby source with Pry, reading source code and more I figured out that this is not possible to do because it is hard-coded into ruby at compile time (wtf?). Anyway, the way to solve this is to simply recompile Ruby. Yeah.
There is also apparently a compile flag which you can set which removes this hard-coded environment: --enable-load-relative
After struggling with this for way to long I finally got this project working, where I have made an easy to use portable version of Ruby. Simply put, a folder with Ruby on it which you can move about, put on a USB stick or whatever, and it still works :)

How to control what Ruby interpreter Puppet uses?

I have an app that requires Ruby 2.1 and use Puppet to provision a handful of servers.
The problem is, when I install on the 2.1 version of Ruby, Puppet starts using that, and it is not supported.
I would like to somehow point Puppet to a 2.0 version of Ruby installed in /opt.
Any suggestions?
Perhaps you could add a shebang line in the .rb file that points to the other version of ruby?
Alternatively you could try to specifically add the bin/ruby location in /opt to the $PATH variable.
Typically, you shouldn't let the system determine the path, but instead provide the full path to the Ruby interpreter you want to execute your script:
/usr/bin/ruby /some/path/to/foo.rb
Or:
/usr/local/bin/ruby1.9.2 /path/to/bar.rb

Should I check in `.ruby-gemset` and/or `.ruby-version`?

I've just updated RVM, and in place of the old .rvmrc, it auto-created .ruby-gemset and .ruby-version.
I've always had .rvmrc files with contents like rvm use --create default#project_name. However, .ruby-version contains the specific Ruby version I'm running rather than default. I'm hesitant to check this in.
Also, I heard someone say on a podcast that one shouldn't check in .ruby-gemset because others may have their own preferences about how to name gemsets.
When should or shouldn't I check in .ruby-gemset and/or .ruby-version?
Specifically:
What are some of the tradeoffs?
How does the type of project affect the decision (for example, applications vs gems)?
If they should be checked in, how does the type of project affect what should go in these files?
Citations from from the creators of tools like rvm, rbenv, etc would be appreciated in an answer.
For standard projects
Check in .ruby-version if your project depends on a ruby like ruby-2.0.0.
Check in .ruby-gemset only if your team agreed on it.
Add .rvmrc to .gitignore so anyone can override .ruby-* files settings with .rvmrc.
For gems
Check in .ruby-version with ruby-1.8.7 only if your project still targets ruby 1.8.7, otherwise check it in only if your gem requires it.
Do not check in .ruby-gemset.
Checking in .rvmrc, .ruby-version or .ruby-gemset?
FOR:
Your project has different branches (say a RubyGems project supporting Ruby 1.8, 1.9 and 2.0 versions). Its better to check in this file, so that your developers don't have to keep on editing these files when they switch branches. The same doesn't apply for an application though, where you'll mostly be working on only one Ruby version.
Same case as above, but say you are running a CI server (say TeamCity/Jenkins/...) which automatically just runs rake spec for every check-in. You don't want to create separate build pipelines for each branch, just for the sake of having a separate rvm use ... for each branch. You just want the Ruby version selected automatically depending on the branch
You have tight control over the environment and all the developers. You either don't need or dictate that they use the same ruby and gemset
You are using Phusion Passenger or Capistrano, which automatically read .rvmrc files and chooses the right ruby for deployment/hosting
Also refer RVM Best Practices
AGAINST:
You can compile your own Ruby in RVM, with some experimental patches, and give it a custom name.
e.g. rvm install 1.9.3 --patch railsexpress,falcon --name ruby-1.9.3-perf
In the above example, I've installed Ruby 1.9.3 with some great speed up patches (btw they are awesome), but rather than calling it 1.9.3, I'm calling it my own name. I would say rvm use ruby-1.9.3-perf whenever I need this. In this case, if the project has its own .ruby-version, then it messes up my environment. In my project, these patches are standard and we actively recommend those. But how developers name the resultant compiled Ruby is up to them
Similarly, people use different gemsets. Some don't use gemsets at all. Some share the same gemset with different (but similar) ruby projects. Given this, again a single .ruby-gemset also doesn't work for everybody
Your project has an obscure ruby version which just says 1.9.3. Your developers first installed the latest Ruby 1.9.3-p329. But they later just update RVM/Rbenv (since they're working on other projects). Their .rvmrc or .ruby-version just breaks, since the latest version of Ruby registered in RVM/Rbenv just changed from ruby-1.9.3-p329 to .ruby-1.9.3-p362, and it will say ruby-1.9.3-p362 not installed. This scenario tends to happen often.
As long as you specify a proper full name for your Ruby version (including patch level), you should be OK. Let's say your project's .ruby-version says ruby-1.9.3-p329. Its easy to compile your own Ruby with all these patches, and still just custom name it ruby-1.9.3-329 just so that the config files will pick up this ruby instead of the standard ruby.
I would include .ruby-version - you and anyone else working on the project, along with your servers, should be using the same version of Ruby.
.ruby-gemset.... up to you, I think.

how do you start ruby 1.9 without rubygems

I want my app to not be able to use any installed gems. Is there a ruby 1.9 startup parameter or way of doing this programmatically?
ruby --disable-gems
is the MRI (1.9) commandline parameter. "It prevents the addition of gem installation directories to the default load path". (The Ruby Programming Language, p. 391)
Edit 25-10-2012: Ruby core had the same idea as #rogerdpack in the comments and added the more verbose ruby --help parameter. Ruby revision!
Looking at the rubygems configuration file, I would attempt to hack out gempath or gemhome to see if you can override (instead of just append to) defaults.
If, for example, setting gempath to be empty, or to point to /dev/null, prevents using system gems, then that would be the way to go.
The main advantage to this, as I see it, is that your anti-rubygems config file can be passed to ruby 1.9 as a startup parameter (so not coded in), well documented, and checked into your repository.
All of this is, of course, disregarding that rubygems is part of ruby 1.9's standard library - so ruby may choke and die if it can't have access to its gems, depending on how much of ruby's base install requires gem functionality. YMMV.

Resources