class Xcodegen::Specparser11X
Public Instance Methods
can_parse_version(version)
click to toggle source
@param version [Semantic::Version]
# File lib/spec/parser/spec_parser_1_1_X.rb, line 6 def can_parse_version(version) version.major == 1 && version.minor == 1 end
parse(spec_version, spec_hash, filename)
click to toggle source
# File lib/spec/parser/spec_parser_1_1_X.rb, line 10 def parse(spec_version, spec_hash, filename) valid_configuration_names = [] configurations = spec_hash['configurations'].map { |name, config| unless config&.key? 'profiles' and config['profiles'].is_a?(Array) and config['profiles'].count > 0 puts Paint["Warning: Configuration with name '#{name}' was skipped as it was invalid"] next nil end valid_configuration_names << name config = Specfile::Configuration.new(name, config['profiles'], config['overrides'] || {}, config['type']) unless config.type != nil puts Paint["Warning: Configuration with name '#{name}' was skipped as its type did not match one of: debug, release"] next nil end next config }.compact raise StandardError.new 'Error: Invalid spec file. Project should have at least one configuration' unless configurations.count > 0 project_base_dir = File.dirname filename return Specfile.new(spec_version, [], configurations, [], project_base_dir) unless spec_hash.key? 'targets' raise StandardError.new "Error: Invalid spec file. Key 'targets' should be a hash" unless spec_hash['targets'].is_a?(Hash) targets = (spec_hash['targets'] || {}).map { |target_name, target_opts| parse_target_data(target_name, target_opts, project_base_dir, valid_configuration_names) }.compact variants = (spec_hash['variants'] || {}).map { |variant_name, variant_targets| parse_variant_data(variant_name, variant_targets, project_base_dir, valid_configuration_names) }.compact if variants.select { |variant| variant.name == '$base' }.count == 0 variants.push Xcodegen::Specfile::Variant.new('$base', [], false) end Specfile.new(spec_version, targets, configurations, variants, project_base_dir) end
parse_target_data(target_name, target_opts, project_base_dir, valid_config_names)
click to toggle source
@return Xcodegen::Specfile::Target
# File lib/spec/parser/spec_parser_1_1_X.rb, line 218 def parse_target_data(target_name, target_opts, project_base_dir, valid_config_names) # Parse target type unless target_opts.key? 'type' puts Paint["Warning: Target #{target_name} has no target type. Ignoring target...", :yellow] return nil end type = target_opts['type'] if type.is_a?(Symbol) type = type.to_s end # : at the start of the type is shorthand for 'com.apple.product-type.' if type.start_with? ':' type[0] = '' raw_type = type type = "com.apple.product-type.#{type}" else raw_type = type end # Parse target platform/type/profiles into a profiles list profiles = nil if target_opts.key? 'profiles' if target_opts['profiles'].is_a?(Array) profiles = target_opts['profiles'] else puts Paint["Warning: Key 'profiles' for target #{target_name} is not an array. Ignoring...", :yellow] end end # Search for platform only if profiles weren't already defined if profiles == nil and target_opts.key? 'platform' raw_platform = target_opts['platform'] # TODO: Add support for 'tvos', 'watchos' unless ['ios', 'mac'].include? raw_platform puts Paint["Warning: Target #{target_name} specifies unrecognised platform '#{raw_platform}'. Ignoring target...", :yellow] return nil end profiles = [raw_type, "platform:#{raw_platform}"] end # Parse target configurations if target_opts.key? 'configurations' unless target_opts['configurations'].is_a?(Hash) puts Paint["Warning: Key 'configurations' for target #{target_name} is not a hash. Ignoring target...", :yellow] return nil end configurations = target_opts['configurations'].map do |config_name, config| unless valid_config_names.include? config_name puts Paint["Warning: Config name #{config_name} for target #{target_name} was not defined in this spec. Ignoring target...", :yellow] return nil end Specfile::Target::Configuration.new(config_name, config, profiles) end elsif target_opts.key? 'configuration' configurations = valid_config_names.map { |name| Specfile::Target::Configuration.new(name, target_opts['configuration'], profiles) } else puts Paint["Warning: Target #{target_name} has no configuration settings. Ignoring target...", :yellow] return nil end unless configurations.count == valid_config_names.count puts Paint["Warning: Missing configurations for target #{target_name}. Expected #{valid_config_names.count}, found: #{configurations.count}. Ignoring target...", :yellow] return nil end # Parse target sources unless target_opts.key? 'sources' puts Paint["Warning: Target #{target_name} contained no valid sources directories. Ignoring target...", :yellow] return nil end if target_opts.key? 'sources' if target_opts['sources'].is_a?(Array) target_sources_dir = target_opts['sources'].map { |src| File.join(project_base_dir, src) } else target_sources_dir = [File.join(project_base_dir, target_opts['sources'])] end target_sources_dir = target_sources_dir.select { |dir| Dir.exist? dir } unless target_sources_dir.count > 0 target_sources_dir = nil end end if target_sources_dir == nil puts Paint["Warning: Target #{target_name} contained no valid sources directories. Ignoring target...", :yellow] return nil end # Parse target resources if target_opts.key? 'i18n-resources' target_resources_dir = File.join(project_base_dir, target_opts['i18n-resources']) else target_resources_dir = target_sources_dir end # Parse excludes if target_opts.key? 'excludes' file_excludes = (target_opts['excludes'] || {})['files'] || [] unless file_excludes.is_a?(Array) puts Paint["Warning: Target #{target_name}'s file excludes was not an array. Ignoring file excludes...", :yellow] file_excludes = [] end else file_excludes = [] end if target_opts.key? 'references' raw_references = target_opts['references'] if raw_references.is_a?(Array) references = raw_references.map { |raw_reference| if raw_reference.is_a?(Hash) path = raw_reference['location'] unless File.exist? File.join(project_base_dir, path) puts Paint["Warning: Reference #{path} could not be found. Ignoring...", :yellow] next nil end if raw_reference['frameworks'] == nil next Specfile::Target::LocalFrameworkReference.new(path, raw_reference) else next Specfile::Target::FrameworkReference.new(path, raw_reference) end else # De-symbolise :sdkroot:-prefixed entries ref = raw_reference.to_s if ref.start_with? 'sdkroot:' if ref.end_with? '.framework' next Specfile::Target::SystemFrameworkReference.new(raw_reference.sub('sdkroot:', '').sub('.framework', '')) else next Specfile::Target::SystemLibraryReference.new(raw_reference.sub('sdkroot:', '')) end else next Specfile::Target::TargetReference.new(raw_reference) end end }.compact else puts Paint["Warning: Key 'references' for target #{target_name} is not an array. Ignoring...", :yellow] references = [] end else references = [] end options = [] if target_opts.key? 'options' if target_opts['options'].is_a?(Hash) if target_opts['options'].key? 'files' if target_opts['options']['files'].is_a?(Hash) options.unshift *target_opts['options']['files'].map { |glob, fileOpts| Specfile::Target::FileOption.new(glob, fileOpts) } else puts Paint["Warning: Key 'files' for target #{target_name}'s options is not a hash. Ignoring...", :yellow] end end if target_opts['options'].key? 'frameworks' if target_opts['options']['frameworks'].is_a?(Hash) options.unshift *target_opts['options']['frameworks'].map { |name, frameworkOpts| Specfile::Target::FrameworkOption.new(name, frameworkOpts) } else puts Paint["Warning: Key 'frameworks' for target #{target_name}'s options is not a hash. Ignoring...", :yellow] end end else puts Paint["Warning: Key 'options' for target #{target_name} is not a hash. Ignoring...", :yellow] end end # Parse target run scripts if target_opts.key? 'scripts' and target_opts['scripts'].is_a?(Array) scripts = target_opts['scripts'].map { |s| next nil if s.start_with? '/' # Script file should be relative to project next nil unless File.exist? File.join(project_base_dir, s) Specfile::Target::RunScript.new s }.compact else scripts = [] end Specfile::Target.new target_name, type, target_sources_dir, configurations, references, options, target_resources_dir, file_excludes, run_scripts=scripts end
parse_variant_data(variant_name, variant_targets, project_base_dir, valid_configuration_names)
click to toggle source
# File lib/spec/parser/spec_parser_1_1_X.rb, line 49 def parse_variant_data(variant_name, variant_targets, project_base_dir, valid_configuration_names) if (variant_name || '').empty? and variant_targets == nil return nil end abstract = false targets = [] (variant_targets || {}).each { |key, value| if key == 'abstract' abstract = true else targets.unshift(parse_variant_target_data(key, value, project_base_dir, valid_configuration_names)) end } Xcodegen::Specfile::Variant.new(variant_name, targets, abstract) end
parse_variant_target_data(target_name, target_opts, project_base_dir, valid_config_names)
click to toggle source
# File lib/spec/parser/spec_parser_1_1_X.rb, line 68 def parse_variant_target_data(target_name, target_opts, project_base_dir, valid_config_names) type = nil raw_type = nil # Parse target type if target_opts.key? 'type' type = target_opts['type'] if type.is_a?(Symbol) type = type.to_s end # : at the start of the type is shorthand for 'com.apple.product-type.' if type.start_with? ':' type[0] = '' raw_type = type type = "com.apple.product-type.#{type}" else raw_type = type end end # Parse target platform/type/profiles into a profiles list profiles = [] if target_opts.key? 'profiles' if target_opts['profiles'].is_a?(Array) profiles = target_opts['profiles'] else puts Paint["Warning: Key 'profiles' for variant override #{target_name} is not an array. Ignoring...", :yellow] end elsif profiles == nil and target_opts.key? 'platform' raw_platform = target_opts['platform'] profiles = [raw_type, "platform:#{raw_platform}"].compact end # Parse target configurations if target_opts.key? 'configurations' if target_opts['configurations'].is_a?(Hash) configurations = target_opts['configurations'].map {|config_name, config| if valid_config_names.include? config_name next nil end Specfile::Target::Configuration.new(config_name, config, profiles) }.compact end elsif target_opts.key? 'configuration' configurations = valid_config_names.map { |name| Specfile::Target::Configuration.new(name, target_opts['configuration'], profiles) } end # Parse target sources if target_opts.key? 'sources' if target_opts['sources'].is_a?(Array) target_sources_dir = target_opts['sources'].map { |src| File.join(project_base_dir, src) } else target_sources_dir = [File.join(project_base_dir, target_opts['sources'])] end target_sources_dir = target_sources_dir.select { |dir| Dir.exist? dir } unless target_sources_dir.count > 0 target_sources_dir = nil end end # Parse target resources if target_opts.key? 'i18n-resources' target_resources_dir = File.join(project_base_dir, target_opts['i18n-resources']) else target_resources_dir = nil end # Parse excludes if target_opts.key? 'excludes' file_excludes = (target_opts['excludes'] || {})['files'] || [] unless file_excludes.is_a?(Array) puts Paint["Warning: Target #{target_name}'s file excludes was not an array. Ignoring file excludes...", :yellow] file_excludes = [] end else file_excludes = [] end if target_opts.key? 'references' raw_references = target_opts['references'] if raw_references.is_a?(Array) references = raw_references.map { |raw_reference| if raw_reference.is_a?(Hash) path = raw_reference['location'] unless File.exist? File.join(project_base_dir, path) puts Paint["Warning: Reference #{path} could not be found. Ignoring...", :yellow] next nil end if raw_reference['frameworks'] == nil next Specfile::Target::LocalFrameworkReference.new(path, raw_reference) else next Specfile::Target::FrameworkReference.new(path, raw_reference) end else # De-symbolise :sdkroot:-prefixed entries ref = raw_reference.to_s if ref.start_with? 'sdkroot:' if ref.end_with? '.framework' next Specfile::Target::SystemFrameworkReference.new(raw_reference.sub('sdkroot:', '').sub('.framework', '')) else next Specfile::Target::SystemLibraryReference.new(raw_reference.sub('sdkroot:', '')) end else next Specfile::Target::TargetReference.new(raw_reference) end end }.compact else puts Paint["Warning: Key 'references' for target #{target_name} is not an array. Ignoring...", :yellow] references = [] end else references = [] end options = [] if target_opts.key? 'options' if target_opts['options'].is_a?(Hash) if target_opts['options'].key? 'files' if target_opts['options']['files'].is_a?(Hash) options.unshift *target_opts['options']['files'].map { |glob, fileOpts| Specfile::Target::FileOption.new(glob, fileOpts) } else puts Paint["Warning: Key 'files' for target #{target_name}'s options is not a hash. Ignoring...", :yellow] end end if target_opts['options'].key? 'frameworks' if target_opts['options']['frameworks'].is_a?(Hash) options.unshift *target_opts['options']['frameworks'].map { |name, frameworkOpts| Specfile::Target::FrameworkOption.new(name, frameworkOpts) } else puts Paint["Warning: Key 'frameworks' for target #{target_name}'s options is not a hash. Ignoring...", :yellow] end end else puts Paint["Warning: Key 'options' for target #{target_name} is not a hash. Ignoring...", :yellow] end end Specfile::Target.new target_name, type, target_sources_dir, configurations, references, options, target_resources_dir, file_excludes end