require "forwardable" require_relative "notification" module NyaConfig class << self attr_reader :parallelism attr_reader :basedir attr_reader :secret attr_reader :webroot attr_reader :notification attr_reader :modules attr_reader :projects def configure(parallelism: 8, basedir:, secret:, webroot:, notification:, modules:, projects:) @parallelism = parallelism @basedir = basedir @secret = secret @webroot = webroot @notification = Notification.new(notification) @modules = modules.map { |mn, s| [mn, s.map { |v, opts| [v, DependencyModule.new(mn, v, opts)] }.to_h] }.to_h @projects = projects.transform_values { |p| Project.new(p) } end def datadir() File.join(basedir, "data") end def tmpdir() File.join(basedir, "tmp") end def module(k, v) modules.fetch(k).fetch(v) end def project(n) projects.fetch(n) end end class Project attr_reader :git, :matrix, :build_proc def initialize(git:, matrix:, build_proc:) @git = git @matrix = matrix.map { |params| params.map { |k, v| [k, NyaConfig.module(k, v.intern)] }.to_h } @build_proc = build_proc end end class DependencyModule attr_reader :module_name, :version def initialize(module_name, version, **opts) @module_name = module_name @version = version.intern @opts = opts end def method_missing(n, *args) # FIXME super unless args.empty? @opts[n] or super end def to_s "#{module_name}-#{version}" end end end module NyaUtils module_function def valid_as_id?(*s) s.all? { |q| q = q.to_s !q.to_s.empty? && !q.include?("..") && /\A[\w.-]+\z/ =~ q } end def normalize_str(s) s.gsub("/", "_").gsub("..", "__") end def equal_str?(s, t) sb = s.bytes; tb = t.bytes sb.size == tb.size && sb.each_with_index.map { |b, i| tb[i] == b }.all? end def find_jobs_for_project(project) Dir[File.join(NyaConfig.datadir, project, "*")] .select { |d| File.directory?(d) } .map { |d| File.basename(d) } .sort.reverse end def find_logs_for_job(project, job) Dir[File.join(NyaConfig.datadir, project, job, "*")] .select { |f| File.file?(f) } .map { |f| File.basename(f).sub(/\.log\z/, "") } .sort end def open_log(project, job, name) File.open(File.join(NyaConfig.datadir, project, job, name + ".log")) { |f| yield f } end def read_log_meta(project, job, name) open_log(project, job, name) { |f| # FIXME lines = f.readlines result_line = lines.reverse_each.find { |l| /\ARESULT=/ =~ l } result = result_line&.split("=")&.last&.chomp time_line = lines.reverse_each.find { |l| /\ATIME=/ =~ l } time = time_line&.split("=")&.last&.chomp { result: result, time: time } } end def flat_time Time.now.utc.iso8601.delete("-:") end end