Automatically download pre-built librun and stc when sources are not available.
...from SWING Jenkins job. A courstesy to those unlucky ones who want to recompile
Smalltalk/X but have no access to stc and librun sources.
require 'net/http'
require 'net/https'
require 'json'
require 'rakelib/extensions.rb'
require 'rakelib/rbspec.rb'
require 'rakelib/vcs.rb'
# Following hack is required to allow passing variable
# values in `make` style, i.e., to allow for
#
# rake PROJECT=stx:jv-branch compile
#
ARGV.each do | arg |
name_and_value = /^([A-Za-z_]+)\w*=(.*)/.match(arg)
if name_and_value
self.class.const_set(name_and_value[1], name_and_value[2])
end
end
# Update PATH for build so build scripts may access
# scripts in `bin` directory. This is required especially
# on Windows as Windows do not ship with some basic tools
# (e.g. zip) by default. As a courtesy to the user, provide
# our own
ENV['PATH'] = "#{ENV['PATH']}#{File::PATH_SEPARATOR}#{File.expand_path('bin')}"
# Return true if running under Jenkins, false otherwise
def jenkins?
return (ENV.has_key? 'WORKSPACE' and
ENV.has_key? 'JOB_NAME' and
ENV.has_key? 'BUILD_ID')
end
# Returns true if and only if this is machine of one of the core developers
# (currently only JV).
# Indeed this is a feeble check and can be easily bypassed by chaning the
# code or by setting a proper environment variable. But this should not hurt
# much as in that case, unauthorized person wouldn't be able to connect to
# stc and librun repository so the build will fail.
def core_developer?
# JV's box: jv@..., vranyj1@...
if (ENV['USER'] == 'jv') or (ENV['USER'] == 'vranyj1')
return true
end
if (ENV['USERNAME'] == 'jv') or (ENV['USERNAME'] == 'vranyj1')
return true
end
return false
end
# A super simple API for Jenkins used to download pre-built stc and librun.
module Jenkins
# Return an a Jenkins build with pre-built stc and librun.
# Used to download pre-build stc and librun
def self.smalltalkx_jv_branch_build()
plat = nil
if win32? then
plat = 'Windows'
elsif linux?
plat = 'Linux'
else
error_unsupported_platform()
end
return Jenkins::Build.new(%Q{https://swing.fit.cvut.cz/jenkins/job/stx_jv_new/ARCH=#{ARCH},PLATFORM=#{plat}N/lastSuccessfulBuild})
end
class Artifact
attr_reader :name
attr_reader :uri
def initialize(name, uri)
@name = name
@uri = uri
end
def download_to(destination)
if not File.exist? destination
if not File.directory? File.dirname(destination)
raise Exception.new("Invalid destination for download: #{destination}")
end
else
if not File.directory? destination
raise Exception.new("Invalid destination for download: #{destination}")
else
destination = File.join(destination, @name)
end
end
Jenkins::get(@uri) do | response |
File.open(destination, "wb") do | file |
response.read_body do | part |
file.write part
end
end
end
end
end
class Build
attr_reader :data
attr_reader :uri
def initialize(uri)
@uri = uri
@data = JSON.parse(Jenkins::get(URI(uri.to_s + '/api/json')))
end
# Return a list of artifacts (as instances of `Jenkins::Artifact`)
# associated with this build.
def artifacts()
if not @artifacts then
@artifacts = @data["artifacts"].collect do | each |
Artifact.new(each['fileName'], URI(@uri.to_s + '/artifact/' + each['relativePath']))
end
end
return @artifacts
end
end
# A private method to GET data over HTTP(S)
def self.get(uri, &block)
# http parameters
http_host = Net::HTTP.new(uri.host, uri.port)
http_host.use_ssl = (uri.scheme == 'https') # simple true enough
if false # host verification not used (yet)
http_host.verify_mode = OpenSSL::SSL::VERIFY_PEER
http_host.cert_store = OpenSSL::X509::Store.new
http_host.cert_store.set_default_paths
http_host.cert_store.add_file('cacert.pem') # file downloaded from curl.haxx.se/ca/cacert.pem
else
http_host.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
# actual download
body = nil
http_host.start do | http |
http.request_get(uri) do | response |
if block then
yield response
else
body = response.body
end
end
end
return body
end
end