Class: Asciidoctor::Cli::Invoker

Inherits:
Object
  • Object
show all
Includes:
Logging
Defined in:
lib/asciidoctor/cli/invoker.rb

Overview

Public Invocation class for starting Asciidoctor via CLI

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Logging

#logger, #message_with_context

Constructor Details

#initialize(*options) ⇒ Invoker

Returns a new instance of Invoker.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/asciidoctor/cli/invoker.rb', line 13

def initialize *options
  @documents = []
  @out = nil
  @err = nil
  @code = 0
  options = options.flatten
  case (first_option = options[0])
  when Options
    @options = first_option
  when ::Hash
    @options = Options.new first_option
  else
    if ::Integer === (result = Options.parse! options)
      @code = result
      @options = nil
    else
      @options = result
    end
  end
end

Instance Attribute Details

#codeObject (readonly)



11
12
13
# File 'lib/asciidoctor/cli/invoker.rb', line 11

def code
  @code
end

#documentsObject (readonly)



10
11
12
# File 'lib/asciidoctor/cli/invoker.rb', line 10

def documents
  @documents
end

#optionsObject (readonly)



9
10
11
# File 'lib/asciidoctor/cli/invoker.rb', line 9

def options
  @options
end

Instance Method Details

#documentObject



161
162
163
# File 'lib/asciidoctor/cli/invoker.rb', line 161

def document
  @documents[0]
end

#invoke!Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/asciidoctor/cli/invoker.rb', line 34

def invoke!
  return unless @options

  old_logger = old_logger_level = nil
  old_verbose, $VERBOSE = $VERBOSE, @options[:warnings]
  opts = {}
  infiles = []
  outfile = nil
  abs_srcdir_posix = nil
  non_posix_env = ::File::ALT_SEPARATOR == RS
  err = @err || $stderr
  show_timings = false
  # NOTE in Ruby 2.7, RubyGems sets SOURCE_DATE_EPOCH if it's not set
  ::ENV.delete 'SOURCE_DATE_EPOCH' if (::ENV.key? 'IGNORE_SOURCE_DATE_EPOCH') && (::Gem.respond_to? :source_date_epoch)

  @options.map do |key, val|
    case key
    when :input_files
      infiles = val
    when :output_file
      outfile = val
    when :source_dir
      if val
        abs_srcdir_posix = ::File.expand_path val
        abs_srcdir_posix = abs_srcdir_posix.tr RS, FS if non_posix_env && (abs_srcdir_posix.include? RS)
      end
    when :destination_dir
      opts[:to_dir] = val if val
    when :attributes
      # NOTE processor will dup attributes internally
      opts[:attributes] = val
    when :timings
      show_timings = val
    when :trace
      # no assignment
    when :verbose
      case val
      when 0
        $VERBOSE = nil
        old_logger, LoggerManager.logger = logger, NullLogger.new
      when 2
        old_logger_level, logger.level = logger.level, ::Logger::Severity::DEBUG
      end
    else
      opts[key] = val unless val.nil?
    end
  end

  if (logger_level = opts.delete :log_level) && !old_logger
    old_logger_level ||= logger.level
    logger.level = logger_level
  end

  if infiles.size == 1
    if (infile0 = infiles[0]) == '-'
      outfile ||= infile0
      stdin = true
    elsif ::File.pipe? infile0
      outfile ||= '-'
    end
  end

  if outfile == '-'
    (tofile = @out) || ((tofile = $stdout).set_encoding UTF_8)
  elsif outfile
    opts[:mkdirs] = true
    tofile = outfile
  else
    opts[:mkdirs] = true
    # automatically calculate outfile based on infile
  end

  if stdin
    # allows use of block to supply stdin, particularly useful for tests
    # NOTE set_encoding returns nil on JRuby 9.1
    block_given? ? (input = yield) : ((input = $stdin).set_encoding UTF_8, UTF_8)
    input_opts = opts.merge to_file: tofile
    if show_timings
      @documents << (::Asciidoctor.convert input, (input_opts.merge timings: (timings = Timings.new)))
      timings.print_report err, '-'
    else
      @documents << (::Asciidoctor.convert input, input_opts)
    end
  else
    infiles.each do |infile|
      input_opts = opts.merge to_file: tofile
      if abs_srcdir_posix && (input_opts.key? :to_dir)
        abs_indir = ::File.dirname ::File.expand_path infile
        if non_posix_env
          abs_indir_posix = (abs_indir.include? RS) ? (abs_indir.tr RS, FS) : abs_indir
        else
          abs_indir_posix = abs_indir
        end
        if abs_indir_posix.start_with? %(#{abs_srcdir_posix}/)
          input_opts[:to_dir] += abs_indir.slice abs_srcdir_posix.length, abs_indir.length
        end
      end
      if show_timings
        @documents << (::Asciidoctor.convert_file infile, (input_opts.merge timings: (timings = Timings.new)))
        timings.print_report err, infile
      else
        @documents << (::Asciidoctor.convert_file infile, input_opts)
      end
    end
  end
  @code = 1 if (logger.respond_to? :max_severity) && logger.max_severity && logger.max_severity >= opts[:failure_level]
rescue ::Exception => e # rubocop:disable Lint/RescueException
  if ::SignalException === e
    @code = e.signo
    # add extra newline if Ctrl+C is used
    err.puts if ::Interrupt === e
  else
    @code = (e.respond_to? :status) ? e.status : 1
    raise e if @options[:trace]
    err.puts ::RuntimeError === e ? %(#{e.message} (#{e.class})) : e.message
    err.puts '  Use --trace to show backtrace'
  end
  nil
ensure
  $VERBOSE = old_verbose
  if old_logger
    LoggerManager.logger = old_logger
  elsif old_logger_level
    logger.level = old_logger_level
  end
end

#read_errorObject



174
175
176
# File 'lib/asciidoctor/cli/invoker.rb', line 174

def read_error
  @err ? @err.string : ''
end

#read_outputObject



170
171
172
# File 'lib/asciidoctor/cli/invoker.rb', line 170

def read_output
  @out ? @out.string : ''
end

#redirect_streams(out, err = nil) ⇒ Object



165
166
167
168
# File 'lib/asciidoctor/cli/invoker.rb', line 165

def redirect_streams out, err = nil
  @out = out
  @err = err
end

#reset_streamsObject



178
179
180
181
# File 'lib/asciidoctor/cli/invoker.rb', line 178

def reset_streams
  @out = nil
  @err = nil
end