ruby-on-railsregexzshterminator

Show Rails version as Prompt Segment in Terminal (ZSH)


My goal is to print the Rails version as a prompt segment to the terminator(terminal) as we enter an ROR project.

I have figured out a way how to display it as a custom segment in the terminator but I am having difficulty extracting the rails version. And to extract the rails version of a ROR project, there's a file called Gemfile.lock which has a list of ruby gems and the exact rails version it has installed for the app.

This is what a Gemfile.lock looks like:

GEM
  remote: https://rubygems.org/
  specs:
    actioncable (7.0.3.1)
      actionpack (= 7.0.3.1)
      activesupport (= 7.0.3.1)
      nio4r (~> 2.0)
      websocket-driver (>= 0.6.1)
    actionmailbox (7.0.3.1)
      actionpack (= 7.0.3.1)
      activejob (= 7.0.3.1)
      activerecord (= 7.0.3.1)
      activestorage (= 7.0.3.1)
      activesupport (= 7.0.3.1)
      mail (>= 2.7.1)
      net-imap
      net-pop
      ....
      ....
      rails (7.0.3.1)
      actioncable (= 7.0.3.1)
      actionmailbox (= 7.0.3.1)
      actionmailer (= 7.0.3.1)
      actionpack (= 7.0.3.1)
      actiontext (= 7.0.3.1)
      actionview (= 7.0.3.1)
      activejob (= 7.0.3.1)
      activemodel (= 7.0.3.1)
     ....
     ....
DEPENDENCIES
  bootsnap
  capybara
  debug
  importmap-rails
  jbuilder
  puma (~> 5.0)
  rails (~> 7.0.3, >= 7.0.3.1)
  redis (~> 4.0)
  selenium-webdriver
  ....
  ....

The gem I want to extract is rails (7.0.3.1)

I am working on a .zshrc file to extract it and so far I have come up with this solution:

ver=`awk -F' ' '$1~/^rails/{print $0}' Gemfile.lock` 

which gives the following output

      rails-dom-testing (~> 2.0)
      rails-html-sanitizer (~> 1.0, >= 1.2.0)
      rails-dom-testing (~> 2.0)
      rails-html-sanitizer (~> 1.1, >= 1.2.0)
    rails (7.0.3.1)
    rails-dom-testing (2.0.3)
    rails-html-sanitizer (1.4.3)
  rails (~> 7.0.3, >= 7.0.3.1) 

As you can see there are multiple gems that include the name rails in them. But I only want to extract the version of this gem rails (7.0.3.1) which has a leading 4 space characters in it.

The expected output I am looking for is just the version of the gem like this: 7.0.3.1 without parenthesis and return as a string type. This will then be stored in a variable and then I will print it out in the terminal as a custom prompt segment with a custom color like:

local color="%F{#f7507b}"
# ver = ``
echo "%{$color%}$ver"

where ver is the variable with the rails version stored.

I have been trying for the past half day but no luck and I have also tried using [[:blank:]] & \s but it doesn't work for this context. I have also tried using rails -v where it outputs the rails version of the project directory we are in, but this will also give an error in rare cases where the user doesn't have installed the ruby version specified in the Gemfile.

The output should give the version of Rails the app uses regardless of whether the user has installed the particular version of Ruby or Rails in their system. And, I think extracting the Rails version from Gemfile.lock is the only way. But if you have any other approach to this solution, I am all ears!

UPDATE:

Thank you all so much for helping me figure this out. Because of you all guys I am now able to see the rails version I am using for the project in my terminal and here is what it looks like:

Screenshot of terminal showing rails version

It is the one to the right of the ruby version prompt. It is 7.1.5.1, that's the rails version!


Solution

  • Using gnu awk you might use for example a pattern with a capture group.

    The pattern matches:

    Example:

    gawk 'match($0, /^[[:space:]]*rails[[:space:]]+\(([0-9][0-9.]*)\)/, a) {
      print a[1]
    }' Gemfile.lock
    

    Output

    7.0.3.1
    

    Or with awk and match

    awk '$1 == "rails" && match($2, /\([0-9][0-9.]*\)/) {
       print substr($2, RSTART+1, RLENGTH-2)
    }' Gemfile.lock