Added `zip()` & `unzip()` extensions to easily create / extract archives from build scripts.
authorJan Vrany <jan.vrany@fit.cvut.cz>
Tue, 24 May 2016 12:03:26 +0100
changeset 7 b6fe3a90f6e0
parent 6 abb35e8d97a7
child 8 659ebd541dd2
Added `zip()` & `unzip()` extensions to easily create / extract archives from build scripts. Under Windows `zip() creates `.zip`, under Linux it creates `.tar.bz2`. As a side effect, `zip()` automatically generates SHA256 checksum and stores it along the archive in in `.zip.sha256` or `.tar.bz2.sha256`. The SHA256 checksum is automatically checked by `unzip()` if corresponding `.sha256` file exists.
rakelib/extensions.rb
rakelib/install.rake
rakelib/setup.rake
rakelib/smalltalk-utils.rb
rakelib/support.rb
rakelib/test.rake
specs/stx-jv.rbspec
--- a/rakelib/extensions.rb	Tue May 24 10:33:45 2016 +0100
+++ b/rakelib/extensions.rb	Tue May 24 12:03:26 2016 +0100
@@ -10,7 +10,7 @@
       r = File.join(File.expand_path(self), arg.to_s())
       if arg.to_s.include? ?* or arg.to_s.include? ??
         r = Dir.glob(r)
-        r.reject! { | f | (f =~ /\.svn|CVS/i) != nil }
+        r.reject! { | f | (f =~ /\.svn|CVS|.hg|.git/i) != nil }
       end
       return r
     end
@@ -56,7 +56,6 @@
     end
   end 
 
-  
   rake_extension("win32?") do
     def win32?      
       if win32_wine?
@@ -180,9 +179,6 @@
 
 
 module RakeFileUtils
-  
-
-
   def make(args = '')
     if win32?
       #sh "make.exe -N -f bc.mak #{args}"
@@ -211,6 +207,98 @@
       sh "#{MAKE} #{args}"
     end
   end
+
+  # Create a compressed archive of `source`. Under Windows it creates
+  # `.zip` archive, otherwise (on Linux) it creates `tar.bz2`. 
+  # 
+  # The archive is created in the same directory as the source and
+  # has the same name unless explicitily specified by `archive:` option. 
+  # If `remove: true` option is set to true, the original (`source`) directory is
+  # removed after adding the archive. 
+  #
+  # As a side-effect, it generates a SHA256 checksum in file .sha256 unles
+  # option `sha256: false` is given.
+  # 
+  # Examples: 
+  #
+  # Create `somedir.bar.bz2` on `/tmp` containg contants of `/tmp/somedir`:
+  #
+  #     zip '/tmp/somedir'
+  #
+  # Create `smalltalkx.bar.bz2` on `/tmp` containg contants of `/tmp/build_dir`
+  # and remove `/tmp/build_dir` afterwards:
+  # 
+  #     zip '/tmp/build_dir', archive: 'smalltalkx', remove: true
+  #  
+  def zip(source, options = {})
+    remove = options[:remove] || false
+    archive = options[:archive] || nil
+    sha256 = options[:sha256] || true
+    suffix = win32? ? '.zip' : '.tar.bz2'
+    if not archive then
+      archive = "#{source}#{suffix}"
+    else 
+      if not archive.end_with? suffix then
+        archive = "#{archive}#{suffix}"
+      end
+    end
+    archive = File.expand_path(archive)
+    chdir File.dirname(source) do
+      if win32? then
+        sh "zip -q -r #{remove ? '-T -m' : ''} \"#{archive}\" \"#{File.basename(source)}\""
+      else 
+        sh "tar cjf \"#{archive}\" #{remove ? '--remove-files' : ''} \"#{File.basename(source)}\""
+      end
+    end        
+    if sha256 then
+      require 'digest'
+      File.open("#{archive}.sha256", "w") do | sum |
+      	sum.write Digest::SHA256.file(archive).hexdigest
+      end
+    end
+  end
+
+  # Extract an (compressed) archive. 
+  # 
+  # Files are extracted to the directory that contains `archive` unless 
+  # options `directory: "some/other/directory` is given. 
+  # 
+  # If file named `#{archive}.sha256` exists then SHA256 checksum is validated
+  # against the one `.sha256` file. If differ, an `Exception` is raised.
+  #
+  # If option `remove: true` is given, then the archive is removed after
+  # all files are extracted. 
+  # 
+  def unzip(archive, options = {})     
+    directory = options[:directory] || File.dirname(archive)
+    remove = options[:remove] || false
+    archive = File.expand_path archive
+    sha256 = "#{archive}.sha256"
+    if File.exist? sha256 then
+      require 'digest'
+      actual = Digest::SHA256.file(archive).hexdigest
+      expected = nil
+      File.open(sha256) { | f | expected = f.read}
+      if actual != expected then
+        raise Exception.new("SHA256 checksum for #{archive} differ (actual #{actual}, expected #{expected}")
+      end
+    end
+
+    chdir directory do      
+      if archive.end_with? '.zip' then
+        sh "unzip \"#{archive}\""
+      elsif archive.end_with? '.tar.bz2' then
+        sh "tar xjf \"#{archive}\""
+      elsif archive.end_with? '.tar.gz' then
+        sh "tar xzf \"#{archive}\""
+      else
+        raise Exception.new("Unknown archive type: #{File.basename(archive)}")        
+      end       
+    end
+    if remove then
+      rm_f archive
+    end
+  end
   
 
   if false #do not use windows wokkaround
--- a/rakelib/install.rake	Tue May 24 10:33:45 2016 +0100
+++ b/rakelib/install.rake	Tue May 24 12:03:26 2016 +0100
@@ -20,13 +20,7 @@
   task :'post'
   task :'main' => :'setup' do 
     if File.exist? ARTIFACTS_DIR / BUILD_NAME then
-      chdir ARTIFACTS_DIR do
-        if win32?
-          sh *%W{zip -q -r #{BUILD_NAME}.zip #{BUILD_NAME}}
-        else
-          sh *%W{tar cjf #{BUILD_NAME}.tar.bz2 #{BUILD_NAME}}
-        end
-      end        
+      zip ARTIFACTS_DIR / BUILD_NAME, move: true
     end
   end
 end
--- a/rakelib/setup.rake	Tue May 24 10:33:45 2016 +0100
+++ b/rakelib/setup.rake	Tue May 24 12:03:26 2016 +0100
@@ -1,4 +1,5 @@
 defined? BUILD_DIR or BUILD_DIR = 'build'
+defined? BUILD_ID or BUILD_ID = ENV['BUILD_NUMBER'] ? "build#{ENV['BUILD_NUMBER']}" : "#{Time.now.strftime("%Y%m%d")}"
 defined? ARTIFACTS_DIR or ARTIFACTS_DIR = 'artifacts'
 defined? REPORT_DIR or REPORT_DIR = 'reports'
 defined? DEBUG or DEBUG = nil
@@ -12,9 +13,8 @@
   load '.config.rake'
 end
 
-if not defined? PROJECT then
-  PROJECT = 'stx:jv-branch'
-end
+defined? PROJECT or PROJECT = 'stx:jv-branch'
+
 
 if not defined? ARCH then
   if ENV.has_key? 'ARCH' then
--- a/rakelib/smalltalk-utils.rb	Tue May 24 10:33:45 2016 +0100
+++ b/rakelib/smalltalk-utils.rb	Tue May 24 12:03:26 2016 +0100
@@ -45,7 +45,5 @@
     def addRakeCompileInfo()
       addInfoChange('rake compile')
     end
-
-
   end
 end
--- a/rakelib/support.rb	Tue May 24 10:33:45 2016 +0100
+++ b/rakelib/support.rb	Tue May 24 12:03:26 2016 +0100
@@ -2,6 +2,7 @@
 require 'rakelib/rbspec.rb'
 require 'rakelib/vcs.rb'
 require 'rakelib/smalltalk-utils.rb'
+require 'rakelib/jenkins-utils.rb'
 
 # Following hack is required to allow passing variable
 # values in `make` style, i.e., to allow for
--- a/rakelib/test.rake	Tue May 24 10:33:45 2016 +0100
+++ b/rakelib/test.rake	Tue May 24 12:03:26 2016 +0100
@@ -15,7 +15,6 @@
 
   report_dir = File.expand_path(REPORT_DIR)
 
-
   if app
     exe_dir = BUILD_DIR / app.directory
     if win32?
@@ -33,7 +32,6 @@
   end
 
   chdir exe_dir do
-
     packages_args = ''
     packages.each { | p | packages_args += " -p #{p}" }
 
@@ -41,11 +39,8 @@
         runner_opts = "-abortOnSEGV -I --execute #{run_report_st}"
     else
         runner_opts = "-I -f #{run_report_st}"
-    end
-
-
-    #sh "#{exe} -I --quick -execue f #{run_report_st} -o #{report_dir} -r #{report} -p #{pkg.name}"
-    sh "#{exe} #{runner_opts} #{global_opts} -D #{report_dir} -r #{report} #{report_opts} #{packages_args}"
+    end    
+    sh "#{exe} #{runner_opts} #{global_opts} -i \"#{BUILD_ID}\" -D \"#{report_dir}\" -r #{report} #{report_opts} #{packages_args}"
   end
 end
 
--- a/specs/stx-jv.rbspec	Tue May 24 10:33:45 2016 +0100
+++ b/specs/stx-jv.rbspec	Tue May 24 12:03:26 2016 +0100
@@ -1,12 +1,5 @@
 load "jv-branch.deps.rake"
 
-# Include Hudson build number of builded by Hudson"
-if ENV['BUILD_NUMBER']
-  build_id="build#{ENV['BUILD_NUMBER']}"
-else
-  build_id="#{Time.now.strftime("%Y%m%d")}"
-end
-
 project :'stx:jv-branch-core' do
   # Core Smalltalk/X - does contain only standard libraries,
   # and development tools. Does not contain any other 'features'
@@ -57,18 +50,35 @@
       end
     end
 
-
-    redefine BUILD_DIR / 'stx' / 'stc' => BUILD_DIR do | t |
-      checkout :'swing:private:hg', 'stx/stc', :branch => 'jv'
+    redefine BUILD_DIR / 'stx' / 'stc' => BUILD_DIR do
+      if core_developer_machine? then
+        checkout :'swing:private:hg', 'stx/stc', :branch => 'jv'
+      else
+        lastSicessfulBuild = Jenkins::Build.new(%q{https://swing.fit.cvut.cz/jenkins/job/stx_jv_new/ARCH=i386,PLATFORM=LinuxN/lastSuccessfulBuild})
+        lastSicessfulBuild.artifacs(/prebuilt\-stc/).each do | each |
+          if not each.name.end_with? '.sha256' then
+            each.download_to(BUILD_DIR / 'stx')
+            unzip BUILD_DIR / 'stx' / each.name
+          end
+        end
+      end
     end
 
-    redefine BUILD_DIR / 'stx' / 'librun' => BUILD_DIR do | t |
-      checkout :'swing:private:hg', 'stx/librun', :branch => 'jv'
+    redefine BUILD_DIR / 'stx' / 'librun' => BUILD_DIR do      
+      if core_developer_machine? then
+        checkout :'swing:private:hg', 'stx/librun', :branch => 'jv'
+      else        
+        lastSicessfulBuild = Jenkins::Build.new(%q{https://swing.fit.cvut.cz/jenkins/job/stx_jv_new/ARCH=i386,PLATFORM=LinuxN/lastSuccessfulBuild})
+        lastSicessfulBuild.artifacs(/prebuilt\-librun/).each do | each |
+          if not each.name.end_with? '.sha256' then
+            each.download_to(BUILD_DIR / 'stx')
+            unzip BUILD_DIR / 'stx' / each.name
+          end
+        end
+      end
     end
 
     if win32?
-
-
       task :'checkout:post' do
         rm_f BUILD_DIR / 'stx' / 'projects' / 'smalltalk' / 'stx_splash.bmp'
       end
@@ -377,7 +387,7 @@
     end
   end
   ver = (ver.split(".")[0..2]).join(".")
-  project.app_version "#{ver}_#{build_id}"
+  project.app_version "#{ver}_#{BUILD_ID}"
   # This is really ugly. We need to clean that up...
   BUILD_NAME.replace "#{project.app_name}-#{project.app_version}_#{ARCH}-#{win32? ? 'win32' : RbConfig::CONFIG['host_os']}"
 end