Ruby Rake Files And Directories manipulation tasks

by Indra 10. November 2011 05:54

These are file and directory manipulation tasks that I use during continuous integration process at MAP Teams(a really cool .NET shop in Jakarta, Indonesia).

List of tasks:
  1. Change Inheritance of some classes before compiling the project(solution)
  2. Copy all files named "copy of app.config" to "app.config" or web.config before compiling solution.
  3. Change version number in assemblyInfo file before committing source code back to repository.
  4. Deleting and creating temp directory hierarchy.
  5. Will be added later.

1. Change Inheritance of some classes before compiling the project(solution)

task :Change_Class_Inheritance do

   classFiles =  File.join(LOC_WORKING_DIRECTORY,"another\\folders/hierarchy","../foldersA/folderB\\MapTeamsPolls/Admin*.aspx.cs")
	# glob with the pattern for  files with " Admin*.aspx.cs" in the directory location
	fileCollection = Dir[classFiles] 
	fileCollection.each do|sourceFile|
		#read file content to string variable
		text = File.read( sourceFile)
		
		#change the line matching the pattern
		text = text.gsub(/(^\s*public partial class .*:\s*)(.*)/, '\1UmbracoEnsuredPage')		
		
		#write the modified content back to file
		File.open(sourceFile, 'w') { |f| f.write(text) }
			
	end
End
    
(Back to index.)

2. Copy all files named "copy of app.config" to "app.config" or web.config before compiling solution.

def CommonUtils.rename_config_files(sourcePath)
	
    #replace backslash to forward slash; glob doesn't work with backslash!!!
    sourceFolder = sourcePath.gsub(/\\/, '/')
    pattern1 = sourceFolder+'/**/copy of *.config'   
    pattern2 = sourceFolder+'/**/*copy.config'
	
    #search recursive directory below solution folder; search for "copy of " files ; remove the "copy of "
    Dir[pattern1, pattern2].each { |configFile| 		
	    FileUtils.cp(configFile, configFile.gsub(/copy of | - Copy/i,'') , :verbose=>true )
    }
end
    
(Back to index.)

3. Change version number in assemblyInfo file before committing source code back to repository

### sourceFolder = project folder containing assemblyInfo; multiple folder
### "1.2.4.5"
def CommonUtils.update_assemblyInfo(sourceFolder, version)

	sourceFolder = sourceFolder.gsub(/\\/, '/') #replace backslash ke forward slash; glob tidak bekerja kalau pakai backslash!!!
	
	pattern1 = sourceFolder+"/**/Properties/AssemblyInfo.cs"
	
	fileCollection = Dir[pattern1]
	
	raise "No Assembly info found in (#{sourceFolder}) ; please check folder" if fileCollection.count == 0
	
	fileCollection.each { |configFile| 	
		text = File.read(configFile)
		newContent = text.gsub!(/Assembly(|File)Version\(\".*\"\)/, "Assembly\\1Version(\"#{version}\")")
	 
		File.open(configFile, 'w') { |f| f.write(newContent) }
	}
end
    
(Back to index.)

4. Deleting and creating temp directory hierarchy.

#target can be folders hierarchy (d:\\folderA/folderB\\folderC/folderD)
def RecreateEmptyFolder(target)
    FileUtils.rm_rf(target, :verbose=>true) if (Dir[target] != [] and Dir[target] != nil )
		
    #make sure no other process is holding the folder
    #sometimes will fail as if rm_rf still not finished while mkdir_p is working
    sleep 3 
    FileUtils.mkdir_p target , :verbose=>true
end
    
(Back to index.)

Tags: ,

Continuous Integration | Snippets | Ruby

How To Execute InstallUtil With WIX 3.5

by Indra 12. September 2011 04:31

I need to execute InstallUtil.exe at the end of a MSI installation created using WIX.

At that moment this link is down (How to Invoke InstallUtil.exe in WiX Custom Action to Call Your Managed Installer Class).

I found out that what I need was Custom Action Type 34 (running an exe with a working directory) from these threads:

These are the code snippets incase the first link is down again.

 

<!-- create custom action -->
<CustomAction Id="AfterCopyingFiles" Directory="DirectoryID_Where_InstallUtil_Is_Copied"
        ExeCommand="[DirectoryID_Where_InstallUtil_Is_Copied]installutil.exe File_Containing_RunInstaller_Attribute.exe" Return="check" Impersonate="yes" Execute="deferred" />

<CustomAction Id="ForUninstall" Directory="DirectoryID_Where_InstallUtil_Is_Copied"
        ExeCommand="[DirectoryID_Where_InstallUtil_Is_Copied]installutil.exe /u File_Containing_RunInstaller_Attribute.exe" Return="check" Impersonate="yes" Execute="immediate" />

<!-- set when custom action will execute -->
<InstallExecuteSequence>
    <!--install-->
    <Custom Action="AfterCopyingFiles" After="InstallFiles">NOT Installed</Custom>
  
    <!--uninstall-->
    <Custom Action="ForUninstall" Before="RemoveFiles">REMOVE="ALL"</Custom>
</InstallExecuteSequence>

 

After reading Chapter 5 from WIX A Developers Guide to Windows Installer I found out 2 more ways to trigger an executable during installation:

  • Custom Action Type 2: using Binary element for storing executable in MSI.
  • Custom Action Type 18: using File element for copying the executable first to the target machine.

code snippet:

<CustomAction Id="CustomActionType2"
   BinaryKey="BinaryElementId_For_The_Executable"
   ExeCommand=""
   Execute="commit"
   Return="ignore" />

<CustomAction Id="CustomActionType18"
   FileKey="FileElementId_For_The_Executable"
   ExeCommand=""
   Execute="commit"
   Return="ignore" />

Tags: ,

Continuous Integration | WIX

SVN Revision Labeller Does Not Work With CruiseControl.NET Beta 1.6

by Indra 19. January 2011 05:53

It's time to upgrade our Continuous Integration platform; I am updating CCNET 1.5 to CCNET 1.6 beta. Configuration Preprocessor with Conditional logic is awesome, I can refactor our distributed build system better with this.

The first error message I got after running the beta version:

 

[CCNet Server:ERROR] INTERNAL ERROR: Could not evaluate expression 'major}.{mino r}.{build}.{revision'
Reason: Syntax error
 ----------


The svnrevisionlabeller plugin from http://code.google.com/p/svnrevisionlabeller/ is not compatible with CCNET beta 1.6.

My quick fix is to edit and recompile the SVN Revision Labeller plugin. You can download the compiled dll here: ccnet.SvnRevisionLabeller.plugin.dll.zip (4.89 kb) and copy to the CCNET installation folder (WARNING! you must change the labeller pattern using '(' and ')' instead of '{' and '}' ).
or follow my steps to recompile:

  • 1. Download the labeller plugin source code.
  • 2. Copy 2 dlls from CCNET 1.6 installation folder to source code's Lib folder :
  •  
    • ThoughtWorks.CruiseControl.Core.dll
    • ThoughtWorks.CruiseControl.Remote.dll
  • 3. Change the regex pattern from { } to ( ) . you can use other pattern. 
    Where to edit the regex token
  • 4. Change your Labeller section in CCNET configuration to use the new token.

This is just my own solution; I haven't contacted the developer for this plugin.

Tags: ,

Continuous Integration