aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew/cmd/man.rb
blob: 36c3f3ba7cef31bd8cb85653e034dd9e748e54a7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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
require "formula"

module Homebrew
  SOURCE_PATH = HOMEBREW_LIBRARY_PATH/"manpages"
  TARGET_MAN_PATH = HOMEBREW_REPOSITORY/"share/man/man1"
  TARGET_DOC_PATH = HOMEBREW_REPOSITORY/"share/doc/homebrew"

  def man
    raise UsageError unless ARGV.named.empty?

    if ARGV.flag? "--link"
      link_man_pages
    else
      regenerate_man_pages
    end
  end

  private

  def link_man_pages
    linked_path = HOMEBREW_PREFIX/"share/man/man1"

    if TARGET_MAN_PATH == linked_path
      odie "The target path is the same as the linked one."
    end

    Dir["#{TARGET_MAN_PATH}/*.1"].each do |page|
      FileUtils.ln_s page, linked_path
    end
  end

  def regenerate_man_pages
    Homebrew.install_gem_setup_path! "ronn"

    convert_man_page("brew.1", build_man_page)
  end

  def build_man_page
    header = (SOURCE_PATH/"header.1.md").read
    footer = (SOURCE_PATH/"footer.1.md").read

    commands = Pathname.glob("#{HOMEBREW_LIBRARY_PATH}/cmd/*.{rb,sh}").
      sort_by { |source_file| source_file.basename.sub(/\.(rb|sh)$/, "") }.
      map { |source_file|
        source_file.read.
          split("\n").
          grep(/^#:/).
          map { |line| line.slice(2..-1) }.
          join("\n")
      }.
      reject { |s| s.strip.empty? }.
      join("\n\n")

    header + commands + footer
  end

  def convert_man_page(page, contents)
    source = SOURCE_PATH/"#{page}.md"
    source.atomic_write(contents)

    convert_with_ronn(source, TARGET_DOC_PATH/"#{page}.html")
    convert_with_ronn(source, TARGET_MAN_PATH/page)
  end

  def convert_with_ronn(source, target)
    shared_args = %W[
      --pipe
      --organization=Homebrew
      --manual=brew
      #{source}
    ]

    format_flag, format_desc = target_path_to_format(target)

    puts "Writing #{format_desc} to #{target}"
    target.atomic_write Utils.popen_read("ronn", format_flag, *shared_args)
  end

  def target_path_to_format(target)
    case target.basename
    when /\.html?$/ then ["--fragment", "HTML fragment"]
    when /\.\d$/    then ["--roff", "man page"]
    else
      odie "Failed to infer output format from '#{target.basename}'."
    end
  end
end