Class: Fastlane::MarkdownDocsGenerator

Inherits:
Object
  • Object
show all
Defined in:
fastlane/lib/fastlane/documentation/markdown_docs_generator.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeMarkdownDocsGenerator

Returns a new instance of MarkdownDocsGenerator.



5
6
7
8
9
10
11
# File 'fastlane/lib/fastlane/documentation/markdown_docs_generator.rb', line 5

def initialize
  require 'fastlane'
  require 'fastlane/documentation/actions_list'
  Fastlane.load_actions

  self.work
end

Instance Attribute Details

#categoriesObject

Returns the value of attribute categories.



3
4
5
# File 'fastlane/lib/fastlane/documentation/markdown_docs_generator.rb', line 3

def categories
  @categories
end

Instance Method Details

#actions_md_contentsObject



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
# File 'fastlane/lib/fastlane/documentation/markdown_docs_generator.rb', line 107

def actions_md_contents
  action_mds = {}

  ActionsList.all_actions do |action|
    @action = action
    @action_filename = filename_for_action(action)

    unless @action_filename
      next
    end

    @custom_content = load_custom_action_md(action)

    if action.superclass != Fastlane::Action
      @custom_content ||= load_custom_action_md(action.superclass)
    end

    template = File.join(Fastlane::ROOT, "lib/assets/ActionDetails.md.erb")
    result = ERB.new(File.read(template), 0, '-').result(binding)

    action_mds[action.action_name] = result
  end

  return action_mds
end

#actions_pathObject



46
47
48
# File 'fastlane/lib/fastlane/documentation/markdown_docs_generator.rb', line 46

def actions_path
  "lib/fastlane/actions/"
end

#all_actions_from_enhancerObject



41
42
43
44
# File 'fastlane/lib/fastlane/documentation/markdown_docs_generator.rb', line 41

def all_actions_from_enhancer
  require 'json'
  @_launches ||= JSON.parse(File.read(File.join(Fastlane::ROOT, "assets/action_ranking.json"))) # root because we're in a temporary directory here
end

#custom_action_docs_pathObject



80
81
82
# File 'fastlane/lib/fastlane/documentation/markdown_docs_generator.rb', line 80

def custom_action_docs_path
  "lib/fastlane/actions/docs/"
end

#filename_for_action(action) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
# File 'fastlane/lib/fastlane/documentation/markdown_docs_generator.rb', line 67

def filename_for_action(action)
  absolute_path = where_is(action)
  filename = File.basename(absolute_path)

  path = File.join(Fastlane::ROOT, actions_path, filename)
  unless File.exist?(path)
    UI.error("Action '#{action.name}' not found in root fastlane project... skipping")
    UI.verbose("Action '#{action.name}' found at #{path}")
    return nil
  end
  filename
end

#fill_built_in_actionsObject



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'fastlane/lib/fastlane/documentation/markdown_docs_generator.rb', line 17

def fill_built_in_actions
  self.categories = {}

  Fastlane::Action::AVAILABLE_CATEGORIES.each { |a| self.categories[readable_category_name(a)] = {} }

  # Fill categories with all built-in actions
  ActionsList.all_actions do |action|
    readable = readable_category_name(action.category)

    if self.categories[readable].kind_of?(Hash)
      self.categories[readable][number_of_launches_for_action(action.action_name)] = action
    else
      UI.error("Action '#{action.name}' doesn't contain category information... skipping")
    end
  end
end

#generate!(target_path: nil) ⇒ Object



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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'fastlane/lib/fastlane/documentation/markdown_docs_generator.rb', line 133

def generate!(target_path: nil)
  require 'yaml'
  FileUtils.mkdir_p(target_path)
  docs_dir = File.join(target_path, "docs")
  generated_actions_dir = File.join("generated", "actions")
  FileUtils.mkdir_p(File.join(docs_dir, generated_actions_dir))

  # Generate actions.md
  template = File.join(Fastlane::ROOT, "lib/assets/Actions.md.erb")
  result = ERB.new(File.read(template), 0, '-').result(binding) # https://web.archive.org/web/20160430190141/www.rrn.dk/rubys-erb-templating-system
  File.write(File.join(docs_dir, "generated", "actions.md"), result)

  # Generate actions sub pages (e.g. generated/actions/slather.md, generated/actions/scan.md)
  all_actions_ref_yml = []
  FileUtils.mkdir_p(File.join(docs_dir, generated_actions_dir))
  ActionsList.all_actions do |action|
    @action = action # to provide a reference in the .html.erb template
    @action_filename = filename_for_action(action)

    unless @action_filename
      next
    end

    # Make sure to always assign `@custom_content`, as we're in a loop and `@` is needed for the `erb`
    @custom_content = load_custom_action_md(action)

    if action.superclass != Fastlane::Action
      # This means, the current method is an alias
      # meaning we're gonna look if the parent class
      # has a custom md file.
      # e.g. `DeliverAction`'s superclass is `UploadToAppStoreAction`
      @custom_content ||= load_custom_action_md(action.superclass)
    end

    template = File.join(Fastlane::ROOT, "lib/assets/ActionDetails.md.erb")
    result = ERB.new(File.read(template), 0, '-').result(binding) # https://web.archive.org/web/20160430190141/www.rrn.dk/rubys-erb-templating-system

    # Actions get placed in "generated/actions" directory
    file_name = File.join(generated_actions_dir, "#{action.action_name}.md")
    File.write(File.join(docs_dir, file_name), result)

    # The action pages when published get moved to the "actions" directory
    # The mkdocs.yml file needs to reference the "actions" directory (not the "generated/actions" directory)
    published_file_name = File.join("actions", "#{action.action_name}.md")
    all_actions_ref_yml << { action.action_name => published_file_name }
  end

  # Modify the mkdocs.yml to list all the actions
  mkdocs_yml_path = File.join(target_path, "mkdocs.yml")
  raise "Could not find mkdocs.yml in #{target_path}, make sure to point to the fastlane/docs repo" unless File.exist?(mkdocs_yml_path)
  mkdocs_yml = YAML.load_file(mkdocs_yml_path)
  hidden_actions_array = mkdocs_yml["nav"].find { |p| !p["_Actions"].nil? }
  hidden_actions_array["_Actions"] = all_actions_ref_yml
  File.write(mkdocs_yml_path, mkdocs_yml.to_yaml)

  # Copy over the assets from the `actions/docs/assets` directory
  Dir[File.join(custom_action_docs_path, "assets", "*")].each do |current_asset_path|
    UI.message("Copying asset #{current_asset_path}")
    FileUtils.cp(current_asset_path, File.join(docs_dir, "img", "actions", File.basename(current_asset_path)))
  end

  UI.success("Generated new docs on path #{target_path}")
end

#load_custom_action_md(action) ⇒ Object



84
85
86
87
88
89
90
91
92
# File 'fastlane/lib/fastlane/documentation/markdown_docs_generator.rb', line 84

def load_custom_action_md(action)
  # check if there is a custom detail view in markdown available in the fastlane code base
  custom_file_location = File.join(Fastlane::ROOT, custom_action_docs_path, "#{action.action_name}.md")
  if File.exist?(custom_file_location)
    UI.verbose("Using custom md file for action #{action.action_name}")
    return File.read(custom_file_location)
  end
  return load_custom_action_md_erb(action)
end

#load_custom_action_md_erb(action) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
# File 'fastlane/lib/fastlane/documentation/markdown_docs_generator.rb', line 94

def load_custom_action_md_erb(action)
  # check if there is a custom detail view as markdown ERB available in the fastlane code base
  custom_file_location = File.join(Fastlane::ROOT, custom_action_docs_path, "#{action.action_name}.md.erb")
  if File.exist?(custom_file_location)
    UI.verbose("Using custom md.erb file for action #{action.action_name}")

    result = ERB.new(File.read(custom_file_location), 0, '-').result(binding) # https://web.archive.org/web/20160430190141/www.rrn.dk/rubys-erb-templating-system

    return result
  end
  return nil
end

#number_of_launches_for_action(action_name) ⇒ Object



34
35
36
37
38
39
# File 'fastlane/lib/fastlane/documentation/markdown_docs_generator.rb', line 34

def number_of_launches_for_action(action_name)
  found = all_actions_from_enhancer.find { |c| c['action'] == action_name.to_s }

  return found["index"] if found
  return 10_000 + rand # new actions that we've never tracked before will be shown at the bottom of the page, need `rand` to not overwrite them
end

#where_is(klass) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'fastlane/lib/fastlane/documentation/markdown_docs_generator.rb', line 50

def where_is(klass)
  # Gets all source files for action
  methods = klass.methods(false).map { |m| klass.method(m) }
  source_files = methods
                 .map(&:source_location)
                 .compact
                 .map { |(file, line)| file }
                 .uniq

  # Return file or error if multiples
  if source_files.size == 1
    return source_files.first
  else
    UI.crash!("Multiple source files were found for action `#{klass}`")
  end
end

#workObject



13
14
15
# File 'fastlane/lib/fastlane/documentation/markdown_docs_generator.rb', line 13

def work
  fill_built_in_actions
end