Posts Tagged ‘ruby’

replacer.rb and deleter.rb

Friday, October 30, 2009

From time to time I find myself needing to replace certain strings globally (eg: in a directory tree), or deleting lines based on a match. I find sed extremely annoying and I don’t manage to get around its syntax. So ruby comes in handy!

replacer.rb

exp_search = '<%=launchBean\.getCustomVersion\(\)%>'
exp_replace = '${xsession.info.launchBean.customVersion}'
directory = '**/'
file_mask = '*.jsp'

Dir.glob(directory+file_mask).each do |file|
  File.open(file, 'r+') do |f|
    content = f.read
    if /#{exp_search}/ =~ content
      s = content.gsub(/#{exp_search}/, exp_replace)
      f.rewind
      f.write s
      puts "#{file}: #{content.split(/#{exp_search}/).size-1} matches"
    end
  end
end

deleter.rb

exp_search = 'useBean.*launchBean'
directory = '**/'
file_mask = '*.jsp'

Dir.glob(directory+file_mask).each do |file|
  count = 0
  content = ""
  File.open(file, 'r+') do |f|
    while line = f.gets
      if /#{exp_search}/ =~ line
        count += 1
      else
        content = content << line
      end
    end
  end
  if count > 0
    File.open(file, 'w') do |f|
      f.write content
      puts "#{file}: #{count} lines deleted"
    end
  end
end

These commands are especially useful if you have to refactor a codebase that doesn’t provide direct support with refactoring tools. In this case, I was refactoring a few hundred JSPs of a legacy system.

Credits to RSF & Ruby One-Liners for most of the code & ideas. rcscript seems to be a bit too much for me at this time, I’m perfectly happy modifying replacer.rb and deleter.rb when I need it.

Running JRuby with Terracotta

Tuesday, October 27, 2009

Lately I have been doing some interesting work integrating Terracotta in our application. We use Terracotta in a very limited scenario: as a tool to implement asynchronous DB replication on PostgreSQL (unfortunately the existing tools out there are not suitable for the kind of usage that we do of PostgreSQL – anyways, I’ll talk more in details about this in further posts).
At a certain point in time we decided to drive some java code with JRuby, in order to process information like log files more efficiently. The java code needed to integrate with Terracotta, so we have had to modify jruby scripts in the following way (eg.: jruby_tc.bat on Windows):

@echo off
rem ---------------------------------------------------------------------------
rem jruby.bat - Start Script for the JRuby Interpreter
rem
rem for info on environment variables, see internal batch script _jrubyvars.bat

setlocal

rem Terracotta
set TC_INSTALL_DIR="C:\Program Files\terracotta\terracotta-3.0.1"
set TC_CONFIG_PATH="C:\whatever\tc-config.xml"
call %TC_INSTALL_DIR%\bin\dso-env.bat -q
set JAVA_OPTS=%JAVA_OPTS% %TC_JAVA_OPTS%

rem Sometimes, when jruby.bat is being invoked from another BAT file,
rem %~dp0 is incorrect and points to the current dir, not to JRuby's bin dir,
rem so we look on the PATH in such cases.
IF EXIST "%~dp0_jrubyvars.bat" (set FULL_PATH=%~dp0) ELSE (set FULL_PATH=%~dp$PATH:0)

call "%FULL_PATH%_jrubyvars.bat" %*

if %JRUBY_BAT_ERROR%==0 "%_STARTJAVA%" %_VM_OPTS% -Xbootclasspath/a:"%JRUBY_CP%" -classpath ^
   "%CP%;%CLASSPATH%" -Djruby.home="%JRUBY_HOME%" -Djruby.lib="%JRUBY_HOME%\lib" ^
   -Djruby.shell="cmd.exe" -Djruby.script=jruby.bat org.jruby.Main %JRUBY_OPTS% %_RUBY_OPTS%
set E=%ERRORLEVEL%

call "%FULL_PATH%_jrubycleanup"

rem 1. exit must be on the same line in order to see local %E% variable!
rem 2. we must use cmd /c in order for the exit code properly returned!
rem    See JRUBY-2094 for more details.
endlocal & cmd /d /c exit /b %E%

The relevant differences are in bold in the batch file above. I’ve called the batch jruby_tc.bat in order to differentiate it from usual jruby.bat. As you can see these changes are for Terracotta 3.0.1 but they should work just the same for Terracotta 3.1