Class: Jazzy::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/jazzy/config.rb

Overview

rubocop:disable Metrics/ClassLength

Defined Under Namespace

Modules: Mixin Classes: Attribute

Constant Summary collapse

SWIFT_BUILD_TOOLS =
%w[spm xcodebuild symbolgraph].freeze
SOURCE_HOSTS =
%w[github gitlab bitbucket].freeze
BUILTIN_THEME_DIR =
Pathname(__dir__) + 'themes'
BUILTIN_THEMES =
BUILTIN_THEME_DIR.children(false).map(&:to_s)
MERGE_MODULES =
%w[all extensions none].freeze

Singleton collapse

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeConfig

rubocop:enable Layout/ArgumentAlignment



538
539
540
541
542
# File 'lib/jazzy/config.rb', line 538

def initialize
  self.class.all_config_attrs.each do |attr|
    attr.set_to_default(self)
  end
end

Class Attribute Details

.all_config_attrsObject (readonly)

Returns the value of attribute all_config_attrs.



96
97
98
# File 'lib/jazzy/config.rb', line 96

def all_config_attrs
  @all_config_attrs
end

.instanceConfig

Returns the current config instance creating one if needed.

Returns:

  • (Config)

    the current config instance creating one if needed.



818
819
820
# File 'lib/jazzy/config.rb', line 818

def self.instance
  @instance ||= new
end

Instance Attribute Details

#base_pathObject

Returns the value of attribute base_path.



99
100
101
# File 'lib/jazzy/config.rb', line 99

def base_path
  @base_path
end

#module_configsObject (readonly)

Module Configs

The user can enter module information in three different ways. This consolidates them into one view for the rest of the code.

1) Single module, back-compatible

--module Foo etc etc (or not given at all)

2) Multiple modules, simple, sharing build params

--modules Foo,Bar,Baz --source-directory Xyz

3) Multiple modules, custom, different build params but

inheriting others from the top level.
This is config-file only.
- modules
  - module: Foo
    source_directory: Xyz
    build_tool_arguments: [a, b, c]

After this we’re left with ‘config.module_configs` that is an array of `Config` objects.



696
697
698
# File 'lib/jazzy/config.rb', line 696

def module_configs
  @module_configs
end

#module_namesObject (readonly)

Returns the value of attribute module_names.



697
698
699
# File 'lib/jazzy/config.rb', line 697

def module_names
  @module_names
end

Class Method Details

.alias_config_attr(name, forward, **opts) ⇒ Object



87
88
89
90
91
92
93
# File 'lib/jazzy/config.rb', line 87

def self.alias_config_attr(name, forward, **opts)
  alias_method name.to_s, forward.to_s
  alias_method "#{name}=", "#{forward}="
  alias_method "#{name}_configured", "#{forward}_configured"
  alias_method "#{name}_configured=", "#{forward}_configured="
  @all_config_attrs << Attribute.new(name, **opts)
end

.config_attr(name, **opts) ⇒ Object

rubocop:enable Naming/AccessorMethodName



79
80
81
82
83
84
85
# File 'lib/jazzy/config.rb', line 79

def self.config_attr(name, **opts)
  attr_accessor name
  attr_accessor "#{name}_configured"

  @all_config_attrs ||= []
  @all_config_attrs << Attribute.new(name, **opts)
end

.parse!Object



549
550
551
552
553
554
555
556
557
558
559
560
# File 'lib/jazzy/config.rb', line 549

def self.parse!
  config = new
  config.parse_command_line
  config.parse_config_file
  PodspecDocumenter.apply_config_defaults(config.podspec, config)

  config.set_module_configs

  config.validate

  config
end

Instance Method Details

#expand_glob_path(path) ⇒ Object



101
102
103
# File 'lib/jazzy/config.rb', line 101

def expand_glob_path(path)
  Pathname(path).expand_path(base_path) # nil means Pathname.pwd
end

#expand_path(path) ⇒ Object



105
106
107
108
# File 'lib/jazzy/config.rb', line 105

def expand_path(path)
  abs_path = expand_glob_path(path)
  Pathname(Dir[abs_path][0] || abs_path) # Use existing filesystem spelling
end

#grouped_attributesObject

Find keyed versions of the attributes, by config file key and then name-in-code Optional block allows filtering/overriding of attribute list.



635
636
637
638
639
640
641
# File 'lib/jazzy/config.rb', line 635

def grouped_attributes
  attrs = self.class.all_config_attrs
  attrs = yield attrs if block_given?
  %i[config_file_key name].map do |property|
    attrs.group_by(&property)
  end
end

#hide_objc?Boolean

Returns:

  • (Boolean)


114
115
116
# File 'lib/jazzy/config.rb', line 114

def hide_objc?
  hide_declarations == 'objc'
end

#hide_swift?Boolean

Returns:

  • (Boolean)


110
111
112
# File 'lib/jazzy/config.rb', line 110

def hide_swift?
  hide_declarations == 'swift'
end

#locate_config_fileObject



744
745
746
747
748
749
750
751
752
# File 'lib/jazzy/config.rb', line 744

def locate_config_file
  return config_file if config_file

  source_directory.ascend do |dir|
    candidate = dir.join('.jazzy.yaml')
    return candidate if candidate.exist?
  end
  nil
end

#module_name?(name) ⇒ Boolean

Returns:

  • (Boolean)


705
706
707
# File 'lib/jazzy/config.rb', line 705

def module_name?(name)
  @module_names_set.include?(name)
end

#module_name_known?Boolean

For podspec query

Returns:

  • (Boolean)


740
741
742
# File 'lib/jazzy/config.rb', line 740

def module_name_known?
  module_name_configured || modules_configured
end

#multiple_modules?Boolean

Returns:

  • (Boolean)


709
710
711
# File 'lib/jazzy/config.rb', line 709

def multiple_modules?
  @module_names.count > 1
end

#parse_command_lineObject

rubocop:disable Metrics/MethodLength



567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
# File 'lib/jazzy/config.rb', line 567

def parse_command_line
  OptionParser.new do |opt|
    opt.banner = 'Usage: jazzy'
    opt.separator ''
    opt.separator 'Options'

    self.class.all_config_attrs.each do |attr|
      attr.attach_to_option_parser(self, opt)
    end

    opt.on('-v', '--version', 'Print version number') do
      puts "jazzy version: #{Jazzy::VERSION}"
      exit
    end

    opt.on('-h', '--help [TOPIC]', 'Available topics:',
           '  usage   Command line options (this help message)',
           '  config  Configuration file options',
           '...or an option keyword, e.g. "dash"') do |topic|
      case topic
      when 'usage', nil
        puts opt
      when 'config'
        print_config_file_help
      else
        print_option_help(topic)
      end
      exit
    end
  end.parse!

  unless ARGV.empty?
    warning "Leftover unused command-line text: #{ARGV}"
  end
end

#parse_config_fileObject



603
604
605
606
607
608
609
610
611
612
613
614
615
# File 'lib/jazzy/config.rb', line 603

def parse_config_file
  config_path = locate_config_file
  return unless config_path

  self.base_path = config_path.parent

  puts "Using config file #{config_path}"
  config_file = read_config_file(config_path)

  attrs_by_conf_key, attrs_by_name = grouped_attributes

  parse_config_hash(config_file, attrs_by_conf_key, attrs_by_name)
end

#parse_config_hash(hash, attrs_by_conf_key, attrs_by_name, override: false) ⇒ Object



617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
# File 'lib/jazzy/config.rb', line 617

def parse_config_hash(hash, attrs_by_conf_key, attrs_by_name, override: false)
  hash.each do |key, value|
    unless attr = attrs_by_conf_key[key]
      message = "Unknown config file attribute #{key.inspect}"
      if matching_name = attrs_by_name[key]
        message +=
          " (Did you mean #{matching_name.first.config_file_key.inspect}?)"
      end
      warning message
      next
    end
    setter = override ? :set : :set_if_unconfigured
    attr.first.method(setter).call(self, value)
  end
end

#parse_module_configsObject



713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
# File 'lib/jazzy/config.rb', line 713

def parse_module_configs
  return [self] unless modules_configured

  raise 'Config file key `modules` must be an array' unless modules.is_a?(Array)

  if modules.first.is_a?(String)
    # Massage format (2) into (3)
    self.modules = modules.map { |mod| { 'module' => mod } }
  end

  # Allow per-module overrides of only some config options
  attrs_by_conf_key, attrs_by_name =
    grouped_attributes { |attr| attr.select(&:per_module) }

  modules.map do |module_hash|
    mod_name = module_hash['module'] || ''
    raise 'Missing `modules.module` config key' if mod_name.empty?

    dup.tap do |module_config|
      module_config.parse_config_hash(
        module_hash, attrs_by_conf_key, attrs_by_name, override: true
      )
    end
  end
end


805
806
807
808
809
810
# File 'lib/jazzy/config.rb', line 805

def print_attr_description(attr)
  attr.description.each { |line| puts "  #{line}" }
  if attr.default && attr.default != ''
    puts "  Default: #{attr.default}"
  end
end


764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
# File 'lib/jazzy/config.rb', line 764

def print_config_file_help
  puts <<-_EOS_

    By default, jazzy looks for a file named ".jazzy.yaml" in the source
    directory and its ancestors. You can override the config file location
    with --config.

    (The source directory is the current working directory by default.
    You can override that with --source-directory.)

    The config file can be in YAML or JSON format. Available options are:

  _EOS_
    .gsub(/^ +/, '')

  print_option_help
end


782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
# File 'lib/jazzy/config.rb', line 782

def print_option_help(topic = '')
  found = false
  self.class.all_config_attrs.each do |attr|
    match = ([attr.name] + attr.command_line).any? do |opt|
      opt.to_s.include?(topic)
    end
    if match
      found = true
      puts
      puts attr.name.to_s.tr('_', ' ').upcase
      puts
      puts "  Config file:   #{attr.config_file_key}"
      cmd_line_forms = attr.command_line.select { |opt| opt.is_a?(String) }
      if cmd_line_forms.any?
        puts "  Command line:  #{cmd_line_forms.join(', ')}"
      end
      puts
      print_attr_description(attr)
    end
  end
  warn "Unknown help topic #{topic.inspect}" unless found
end

#read_config_file(file) ⇒ Object



754
755
756
757
758
759
760
761
762
# File 'lib/jazzy/config.rb', line 754

def read_config_file(file)
  case File.extname(file)
    when '.json'
      JSON.parse(File.read(file))
    when '.yaml', '.yml'
      YAML.safe_load(File.read(file))
    else raise "Config file must be .yaml or .json, but got #{file.inspect}"
  end
end

#set_module_configsObject



699
700
701
702
703
# File 'lib/jazzy/config.rb', line 699

def set_module_configs
  @module_configs = parse_module_configs
  @module_names = module_configs.map(&:module_name)
  @module_names_set = Set.new(module_names)
end

#theme_directory=(theme_directory) ⇒ Object



544
545
546
547
# File 'lib/jazzy/config.rb', line 544

def theme_directory=(theme_directory)
  @theme_directory = theme_directory
  Doc.template_path = theme_directory + 'templates'
end

#validateObject



643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
# File 'lib/jazzy/config.rb', line 643

def validate
  if source_host_configured &&
     source_host_url.nil? &&
     source_host_files_url.nil?
    warning 'Option `source_host` is set but has no effect without either ' \
      '`source_host_url` or `source_host_files_url`.'
  end

  if modules_configured && module_name_configured
    raise 'Options `modules` and `module` are both set which is not supported. ' \
      'To document multiple modules, use just `modules`.'
  end

  if modules_configured && podspec_configured
    raise 'Options `modules` and `podspec` are both set which is not supported.'
  end

  module_configs.each(&:validate_module)
end

#validate_moduleObject



663
664
665
666
667
668
669
670
# File 'lib/jazzy/config.rb', line 663

def validate_module
  if objc_mode &&
     build_tool_arguments_configured &&
     (framework_root_configured || umbrella_header_configured)
    warning 'Option `build_tool_arguments` is set: values passed to ' \
      '`framework_root` or `umbrella_header` may be ignored.'
  end
end

#warning(message) ⇒ Object



562
563
564
# File 'lib/jazzy/config.rb', line 562

def warning(message)
  warn "WARNING: #{message}"
end