ruby-on-railsregexbashzshterminator

Matching a string with whitespace character in bash


Basically, my goal is to print the rails version as a prompt segment to the terminator(terminal) as we enter a 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 that has rails version stored in it.

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. So I think extracting the rails version from Gemfile.lock is the only way. But if you have any other approach towards this solution, I am all ears!


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