mirror of
https://github.com/cpm-cmake/CPM.cmake.git
synced 2025-11-16 22:27:41 -05:00
* Add missing packageproject options * Fix typos with codespell * Update test/style/CMakeLists.txt Co-authored-by: Lars Melchior <TheLartians@users.noreply.github.com> * fix-cmake-format --------- Co-authored-by: Lars Melchior <TheLartians@users.noreply.github.com>
207 lines
5.7 KiB
Ruby
207 lines
5.7 KiB
Ruby
require 'fileutils'
|
|
require 'open3'
|
|
require 'tmpdir'
|
|
require 'test/unit'
|
|
|
|
module TestLib
|
|
TMP_DIR = File.expand_path(ENV['CPM_INTEGRATION_TEST_DIR'] || File.join(Dir.tmpdir, 'cpm-test', Time.now.strftime('%Y_%m_%d-%H_%M_%S')))
|
|
CPM_PATH = File.expand_path('../../cmake/CPM.cmake', __dir__)
|
|
|
|
TEMPLATES_DIR = File.expand_path('templates', __dir__)
|
|
|
|
# Environment variables which are read by cpm
|
|
CPM_ENV = %w(
|
|
CPM_USE_LOCAL_PACKAGES
|
|
CPM_LOCAL_PACKAGES_ONLY
|
|
CPM_DOWNLOAD_ALL
|
|
CPM_DONT_UPDATE_MODULE_PATH
|
|
CPM_DONT_CREATE_PACKAGE_LOCK
|
|
CPM_INCLUDE_ALL_IN_PACKAGE_LOCK
|
|
CPM_USE_NAMED_CACHE_DIRECTORIES
|
|
CPM_SOURCE_CACHE
|
|
)
|
|
def self.clear_env
|
|
CPM_ENV.each { ENV[_1] = nil }
|
|
end
|
|
end
|
|
|
|
puts "Warning: test directory '#{TestLib::TMP_DIR}' already exists" if File.exist?(TestLib::TMP_DIR)
|
|
raise "Cannot find 'CPM.cmake' at '#{TestLib::CPM_PATH}'" if !File.file?(TestLib::CPM_PATH)
|
|
|
|
puts "Running CPM.cmake integration tests"
|
|
puts "Temp directory: '#{TestLib::TMP_DIR}'"
|
|
|
|
# Clean all CPM-related env vars
|
|
TestLib.clear_env
|
|
|
|
class Project
|
|
def initialize(src_dir, bin_dir)
|
|
@src_dir = src_dir
|
|
@bin_dir = bin_dir
|
|
end
|
|
|
|
attr :src_dir, :bin_dir
|
|
|
|
def create_file(target_path, text, args = {})
|
|
target_path = File.join(@src_dir, target_path)
|
|
|
|
# tweak args
|
|
args[:cpm_path] = TestLib::CPM_PATH if !args[:cpm_path]
|
|
args[:packages] = [args[:package]] if args[:package] # if args contain package, create the array
|
|
args[:packages] = args[:packages].join("\n") if args[:packages] # join all packages if any
|
|
|
|
File.write target_path, text % args
|
|
end
|
|
|
|
def create_file_from_template(target_path, source_path, args = {})
|
|
source_path = File.join(@src_dir, source_path)
|
|
raise "#{source_path} doesn't exist" if !File.file?(source_path)
|
|
src_text = File.read source_path
|
|
create_file target_path, src_text, args
|
|
end
|
|
|
|
# common function to create ./CMakeLists.txt from ./lists.in.cmake
|
|
def create_lists_from_default_template(args = {})
|
|
create_file_from_template 'CMakeLists.txt', 'lists.in.cmake', args
|
|
end
|
|
|
|
CommandResult = Struct.new :out, :err, :status
|
|
def configure(extra_args = '')
|
|
CommandResult.new *Open3.capture3("cmake -S #{@src_dir} -B #{@bin_dir} #{extra_args}")
|
|
end
|
|
def build(extra_args = '')
|
|
CommandResult.new *Open3.capture3("cmake --build #{@bin_dir} #{extra_args}")
|
|
end
|
|
|
|
class CMakeCache
|
|
class Entry
|
|
def initialize(val, type, advanced, desc)
|
|
@val = val
|
|
@type = type
|
|
@advanced = advanced
|
|
@desc = desc
|
|
end
|
|
attr :val, :type, :advanced, :desc
|
|
alias_method :advanced?, :advanced
|
|
def inspect
|
|
"(#{val.inspect} #{type}" + (advanced? ? ' ADVANCED)' : ')')
|
|
end
|
|
end
|
|
|
|
Package = Struct.new(:ver, :src_dir, :bin_dir)
|
|
|
|
def self.from_dir(dir)
|
|
entries = {}
|
|
cur_desc = ''
|
|
file = File.join(dir, 'CMakeCache.txt')
|
|
return nil if !File.file?(file)
|
|
File.readlines(file).each { |line|
|
|
line.strip!
|
|
next if line.empty?
|
|
next if line.start_with? '#' # comment
|
|
if line.start_with? '//'
|
|
cur_desc += line[2..]
|
|
else
|
|
m = /(.+?)(-ADVANCED)?:([A-Z]+)=(.*)/.match(line)
|
|
raise "Error parsing '#{line}' in #{file}" if !m
|
|
entries[m[1]] = Entry.new(m[4], m[3], !!m[2], cur_desc)
|
|
cur_desc = ''
|
|
end
|
|
}
|
|
CMakeCache.new entries
|
|
end
|
|
|
|
def initialize(entries)
|
|
@entries = entries
|
|
|
|
package_list = self['CPM_PACKAGES']
|
|
@packages = if package_list
|
|
# collect package data
|
|
@packages = package_list.split(';').map { |name|
|
|
[name, Package.new(
|
|
self["CPM_PACKAGE_#{name}_VERSION"],
|
|
self["CPM_PACKAGE_#{name}_SOURCE_DIR"],
|
|
self["CPM_PACKAGE_#{name}_BINARY_DIR"]
|
|
)]
|
|
}.to_h
|
|
else
|
|
{}
|
|
end
|
|
end
|
|
|
|
attr :entries, :packages
|
|
|
|
def [](key)
|
|
e = @entries[key]
|
|
return nil if !e
|
|
e.val
|
|
end
|
|
end
|
|
def read_cache
|
|
CMakeCache.from_dir @bin_dir
|
|
end
|
|
end
|
|
|
|
class IntegrationTest < Test::Unit::TestCase
|
|
self.test_order = :defined # run tests in order of definition (as opposed to alphabetical)
|
|
|
|
def cleanup
|
|
# Clear cpm-related env vars which may have been set by the test
|
|
TestLib.clear_env
|
|
end
|
|
|
|
# extra assertions
|
|
|
|
def assert_success(res)
|
|
msg = build_message(nil, "command status was expected to be a success, but failed with code <?> and STDERR:\n\n#{res.err}", res.status.to_i)
|
|
assert_block(msg) { res.status.success? }
|
|
end
|
|
|
|
def assert_failure(res)
|
|
msg = build_message(nil, "command status was expected to be a failure, but succeeded")
|
|
assert_block(msg) { !res.status.success? }
|
|
end
|
|
|
|
def assert_same_path(a, b)
|
|
msg = build_message(nil, "<?> expected but was\n<?>", a, b)
|
|
assert_block(msg) { File.identical? a, b }
|
|
end
|
|
|
|
# utils
|
|
class << self
|
|
def startup
|
|
@@test_dir = File.join(TestLib::TMP_DIR, self.name.
|
|
# to-underscore conversion from Rails
|
|
gsub(/::/, '/').
|
|
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
|
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
|
tr("-", "_").
|
|
downcase
|
|
)
|
|
end
|
|
end
|
|
|
|
def cur_test_dir
|
|
@@test_dir
|
|
end
|
|
|
|
def make_project(name: nil, from_template: nil)
|
|
test_name = local_name
|
|
test_name = test_name[5..] if test_name.start_with?('test_')
|
|
|
|
base = File.join(cur_test_dir, test_name)
|
|
base += "-#{name}" if name
|
|
src_dir = base + '-src'
|
|
|
|
FileUtils.mkdir_p src_dir
|
|
|
|
if from_template
|
|
from_template = File.join(TestLib::TEMPLATES_DIR, from_template)
|
|
raise "#{from_template} is not a directory" if !File.directory?(from_template)
|
|
FileUtils.copy_entry from_template, src_dir
|
|
end
|
|
|
|
Project.new src_dir, base + '-bin'
|
|
end
|
|
end
|