# frozen_string_literal: true require 'psych' require 'pathname' require 'base64' class ComposeFileService class << self def parse(compose_content, compose_file_path) compose_data = parse_compose_content_to_object(compose_content) env_files = prepare_services_env_files(compose_data['services']).flatten.uniq config_files = fetch_configs(compose_data['configs']) prepare_dependencies(env_files, config_files, compose_file_path) end private def prepare_dependencies(env_files, config_files, compose_file_path) prepare_dependency_files_data(env_files + config_files, compose_file_path) end def prepare_dependency_files_data(dependency_files, compose_file_path) dependency_files.map do |dependency_file| dependency_file_data = Psych.load(File.read("#{compose_file_path}/#{dependency_file}")) { path: dependency_file, source: dependency_file, content: Base64.encode64(dependency_file_data), } end rescue Errno::ENOENT => e dependency_path = e.message.split('- ').last raise Uffizzi::Error.new("The config file #{dependency_path} does not exist") end def fetch_configs(configs_data) return [] if configs_data.nil? Uffizzi.ui.say("Unsupported type of #{:configs} option") unless configs_data.is_a?(Hash) configs = [] configs_data.each_pair do |config_name, config_data| Uffizzi.ui.say("#{config_name} has an empty file") if config_data['file'].empty? || config_data['file'].nil? configs << prepare_file_path(config_data['file']) end configs end def prepare_file_path(file_path) pathname = Pathname.new(file_path) pathname.cleanpath.to_s.strip.delete_prefix('/') end def parse_env_file(env_file) case env_file when String Uffizzi.ui.say('env_file contains an empty value') if env_file.nil? || env_file.empty? [prepare_file_path(env_file)] when Array Uffizzi.ui.say('env_file contains an empty value') if env_file.any? { |file| file.nil? || file.empty? } env_file.map { |env_file_path| prepare_file_path(env_file_path) } else Uffizzi.ui.say("Unsupported type of #{:env_file} option") end end def prepare_services_env_files(services) return [] if services.nil? services.keys.map do |service| service_env_files = prepare_service_env_files(services.fetch(service)) service_env_files end end def prepare_service_env_files(service_data) env_files_data = [] service_data.each_pair do |key, value| key_sym = key.to_sym if key_sym == :env_file env_files_data << parse_env_file(value) end end env_files_data end def parse_compose_content_to_object(compose_content) begin compose_data = Psych.safe_load(compose_content, aliases: true) rescue Psych::SyntaxError Uffizzi.ui.say('Invalid compose file') end Uffizzi.ui.say('Unsupported compose file') if compose_data.nil? compose_data end end end