3
\$\begingroup\$

In our applications we have a version file that has three variables that are then joined to create a string that can be used for the semantic version.

The file looks like:

# frozen_string_literal: true
major = 0
minor = 1
patch = 0
PORTAL_VERSION = [major, minor, patch].join('.')

And then we update it using the following from our CI server:

@version = '0.1.1' # this is passed from somewhere
puts 'updating version'
version_file = File.open("version.rb").read
version = @version.split('.')
version_file = version_file.gsub(/(major = \w)/, "major = #{version[0]}")
version_file = version_file.gsub(/(minor = \w)/, "minor = #{version[1]}")
version_file = version_file.gsub(/(patch = \w)/, "patch = #{version[2]}")
File.open('version.rb', 'wb') { |file| file.write(version_file) }
puts "updated version to #{@version}"

Is there a better way to do the replacement using the regex? As by having to find each line and then replace it feels a little dirty, plus if there was or wasn't spaces between the variable name and value it wouldn't work. So it feels a little fragile.

asked May 8, 2018 at 14:40
\$\endgroup\$
1
  • \$\begingroup\$ Why not generate a new version.rb from scratch instead of trying to edit it? \$\endgroup\$ Commented May 8, 2018 at 20:44

1 Answer 1

2
\$\begingroup\$

There might be two easier options:

  • Generate the file using a template file something like the following

    major = {{major}}
    minor = {{minor}}
    patch = {{patch}}
    

that has strings that are easy to search for. You could also use ERB to generate the file.

  • Put the logic in your version.rb file something like:

    PORTAL_VERSION = '1.2.3'
    major, minor, path = PORTAL_VERSION.split('.').map(&:to_i)
    

This way you would just have to replace the first line.

  • If you want to do it using your logic I would change the regex from /(patch = \w)/ to /(patch\s*=\s*\w+)/ this would handle extra whitespace and version numbers bigger than 9

  • Note you can also do variable substitution in Regexes so you could write your code as:

    ['major', 'minor', 'patch'].each.with_index do |key, i|
     version_file.sub!(/(#{key}\s*=\s*\w+)/, "#{key} = #{version[i]}")
    end
    

Note that gsub isn't necessary as you only expect one occurrence.

answered May 8, 2018 at 23:50
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.