Do not ship VDB as part of default build / toy archive
The reason is that few people used it and those who did (or will)
are those who may want to hack on it. To make this easier when using
toy archive, we won't ship VDB in toy archive anymore and instead
we'll document on how to install it in VDB's `README.md`
require 'net/http'
require 'net/https'
require 'json'
require 'rakelib/extensions.rb'
require 'rakelib/rbspec.rb'
require 'rakelib/scm.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)
self.class.const_set(name_and_value[1], name_and_value[2]) if name_and_value
end
# Update PATH for build so build scripts may access scripts and programs
# 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.
# NOTE that this MUST be the first entry in the PATH to be able to override
# MINGW/MSYS make.exe with Borland's ancient make.exe (sigh, St/X still deals
# with dinosaurs)
ENV['PATH'] = "#{File.expand_path('bin')};#{File::PATH_SEPARATOR}#{ENV['PATH']}"
# Return true if running under Jenkins, false otherwise
def jenkins?
(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 changing 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@...
user = ENV['USER'] || ENV['USERNAME']
(user == 'jv') or (user == 'vranyj1') ? true : false
end
# ArtifactRepository module provides API for downloading (binary) files from
# some sort of - well - artifact repository. A repository contains multiple
# builds (currently the API provides only access to `latestBuild()`), build
# contains multipe `Artifact`s. An `Artifact` is essentially a downloadable
# (binary) file.
#
# Currently only Jenkins-based repository is provided (see class `Jenkins`
# within this module)
module ArtifactRepository
private
# 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) {|response| block ? (yield response) : (body = response.body)}
end
body
end
public
class Artifact
attr_reader :name
attr_reader :uri
def initialize(name, uri)
@name = name
@uri = uri
end
def download_to(destination)
if !File.exist? destination
raise Exception.new("Invalid destination for download: #{destination}") unless File.directory? File.dirname(destination)
else
if !File.directory? destination
raise Exception.new("Invalid destination for download: #{destination}")
else
destination = File.join(destination, @name)
end
end
ArtifactRepository::get(@uri) do |response|
File.open(destination, 'wb') do |file|
response.read_body {|part| file.write part}
end
end
end
end
# Jenkins-based artifact repository.
class Jenkins
def initialize(uri)
@uri = uri
end
def latestBuild()
return Build.new(@uri + '/lastStableBuild')
end
class Build
attr_reader :data
attr_reader :uri
def initialize(uri)
@uri = uri
@data = JSON.parse(ArtifactRepository::get(URI(uri.to_s + '/api/json')))
end
# Return a list of artifacts (as instances of `ArtifactRepository::Artifact`)
# associated with this build.
def artifacts
unless @artifacts
@artifacts = @data['artifacts'].collect {|each| Artifact.new(each['fileName'], URI(@uri.to_s + '/artifact/' + each['relativePath']))}
end
@artifacts
end
end # class ArtifactRepository::Jenkins::Build
end # class ArtifactRepository::Jenkins
class PlainHTTPListing
def initialize(uri)
@uri = uri
@html_data = Net::HTTP.get(URI(uri))
end
def latestBuild()
return Build.new(@uri + latest_build + '/') # dont forget trailing '/'!
end
class Build
attr_reader :uri, :html_data
def initialize(uri)
@uri = uri
@html_data = Net::HTTP.get(URI(uri))
end
def artifacts
unless @artifacts
# get latest build file list
@artifacts = lastest_build_files(Array.new, String.new).collect {|each_file| Artifact.new(each_file, URI(@uri + each_file))}
end
@artifacts
end
private
# parse HTML via regexp (yes, bad idea but Apache can't serve natively JSON)
# retuns Array of String(s) - filenames and their suffixes
def parse_html_directories(html_build_directory_list)
files_and_suffixes = html_build_directory_list.scan(/(smalltalkx-jv-branch-\d+.\d+.\d+_build\d+[a-zA-Z0-9_\-]+\.|tar\.bz2|zip|7z|7zip|\.sha256|\.sha512)/)
files_and_suffixes.flatten
end
# create file array where the file part and its suffix will be merged together
# returns Array of String filenames without any duplicities (needed due to HTML nature (a href))
def lastest_build_files(stx_latest_build_files, stx_file)
parse_html_directories(@html_data).each do |file_part|
if file_part.match(/\.$/) # only a file_part has a . at the end
stx_latest_build_files.push(stx_file) unless stx_file.empty?
stx_file = String.new # empty current String content
stx_file = file_part
else
stx_file = stx_file + file_part
end
end
# prune (duplicities)
stx_latest_build_files.uniq!
end
end # class ArtifactRepository::PlainHTTPListing::Build
private
# find newest build contains date: yyyy-mm-dd_buildId
def latest_build
directory_list.max
end
# get Array of directories
def directory_list
directories=@html_data.scan(/\d{4}-\d{2}-\d{2}_\d+/)
directories.uniq! # remove duplicates
end
end # class ArtifactRepository::PlainHTTPListing
end # module ArtifactRepository