mirror of https://github.com/rails/rails
refactors and fixes in guides generation [ci skip]
This commit is not precisely atomic, but the changes have evolved, summary: * The ENV-based interface has been moved upwards, the generator has now a conventional initializer. * RAILS_VERSION is now assumed to be a Git tag. A blank RAILS_VERSION means edge guides. * In consequence, the EDGE env variable is gone. * The "local" version is also gone, the current SHA1 is computed for edge guides. * Assumes guides are generated from a repo checkout (time ago users could generate them from gems.) * The WARNINGS flag is gone in consequence, you cannot disable warnings. * The `api_link` Markdown helper is fixed. * Docs about usage have one single place: rake guides:help. * Links in guides have been revised.
This commit is contained in:
parent
4fed08fa78
commit
771a802c37
|
@ -1,10 +1,8 @@
|
|||
namespace :guides do
|
||||
|
||||
desc 'Generate guides (for authors), use ONLY=foo to process just "foo.md"'
|
||||
task generate: "generate:html"
|
||||
|
||||
namespace :generate do
|
||||
|
||||
desc "Generate HTML guides"
|
||||
task :html do
|
||||
ENV["WARNINGS"] = "1" # authors can't disable this
|
||||
|
@ -18,7 +16,7 @@ namespace :guides do
|
|||
abort "Please run `setupkindlerb` to install kindlegen"
|
||||
end
|
||||
unless `convert` =~ /convert/
|
||||
abort "Please install ImageMagick`"
|
||||
abort "Please install ImageMagick"
|
||||
end
|
||||
ENV["KINDLE"] = "1"
|
||||
Rake::Task["guides:generate:html"].invoke
|
||||
|
@ -33,7 +31,7 @@ namespace :guides do
|
|||
|
||||
desc "Show help"
|
||||
task :help do
|
||||
puts <<-help
|
||||
puts <<HELP
|
||||
|
||||
Guides are taken from the source directory, and the result goes into the
|
||||
output directory. Assets are stored under files, and copied to output/files as
|
||||
|
@ -46,8 +44,9 @@ All of these processes are handled via rake tasks, here's a full list of them:
|
|||
#{%x[rake -T]}
|
||||
Some arguments may be passed via environment variables:
|
||||
|
||||
WARNINGS=1
|
||||
Internal links (anchors) are checked, also detects duplicated IDs.
|
||||
RAILS_VERSION=tag
|
||||
If guides are being generated for a specific Rails version set the Git tag
|
||||
here, otherwise the current SHA1 is going to be used to generate edge guides.
|
||||
|
||||
ALL=1
|
||||
Force generation of all guides.
|
||||
|
@ -65,15 +64,12 @@ Some arguments may be passed via environment variables:
|
|||
Use it when you want to generate translated guides in
|
||||
source/<GUIDES_LANGUAGE> folder (such as source/es)
|
||||
|
||||
EDGE=1
|
||||
Indicate generated guides should be marked as edge.
|
||||
|
||||
Examples:
|
||||
$ rake guides:generate ALL=1
|
||||
$ rake guides:generate EDGE=1
|
||||
$ rake guides:generate:kindle EDGE=1
|
||||
$ rake guides:generate ALL=1 RAILS_VERSION=v5.1.0
|
||||
$ rake guides:generate ONLY=migrations
|
||||
$ rake guides:generate:kindle
|
||||
$ rake guides:generate GUIDES_LANGUAGE=es
|
||||
help
|
||||
HELP
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,17 +1,27 @@
|
|||
pwd = File.dirname(__FILE__)
|
||||
$:.unshift pwd
|
||||
$:.unshift __dir__
|
||||
|
||||
begin
|
||||
# Guides generation in the Rails repo.
|
||||
as_lib = File.join(pwd, "../activesupport/lib")
|
||||
ap_lib = File.join(pwd, "../actionpack/lib")
|
||||
as_lib = File.expand_path("../activesupport/lib", __dir__)
|
||||
ap_lib = File.expand_path("../actionpack/lib", __dir__)
|
||||
av_lib = File.expand_path("../actionview/lib", __dir__)
|
||||
|
||||
$:.unshift as_lib if File.directory?(as_lib)
|
||||
$:.unshift ap_lib if File.directory?(ap_lib)
|
||||
rescue LoadError
|
||||
# Guides generation from gems.
|
||||
gem "actionpack", ">= 3.0"
|
||||
end
|
||||
$:.unshift as_lib if File.directory?(as_lib)
|
||||
$:.unshift ap_lib if File.directory?(ap_lib)
|
||||
$:.unshift av_lib if File.directory?(av_lib)
|
||||
|
||||
require "rails_guides/generator"
|
||||
RailsGuides::Generator.new.generate
|
||||
require "active_support/core_ext/object/blank"
|
||||
|
||||
env_value = ->(name) { ENV[name].presence }
|
||||
env_flag = ->(name) { "1" == env_value[name] }
|
||||
|
||||
version = env_value["RAILS_VERSION"]
|
||||
edge = `git rev-parse HEAD`.strip unless version
|
||||
|
||||
RailsGuides::Generator.new(
|
||||
edge: edge,
|
||||
version: version,
|
||||
all: env_flag["ALL"],
|
||||
only: env_value["ONLY"],
|
||||
kindle: env_flag["KINDLE"],
|
||||
language: env_value["GUIDES_LANGUAGE"]
|
||||
).generate
|
||||
|
|
|
@ -1,54 +1,3 @@
|
|||
# ---------------------------------------------------------------------------
|
||||
#
|
||||
# This script generates the guides. It can be invoked via the
|
||||
# guides:generate rake task within the guides directory.
|
||||
#
|
||||
# Guides are taken from the source directory, and the resulting HTML goes into the
|
||||
# output directory. Assets are stored under files, and copied to output/files as
|
||||
# part of the generation process.
|
||||
#
|
||||
# Some arguments may be passed via environment variables:
|
||||
#
|
||||
# WARNINGS
|
||||
# If you are writing a guide, please work always with WARNINGS=1. Users can
|
||||
# generate the guides, and thus this flag is off by default.
|
||||
#
|
||||
# Internal links (anchors) are checked. If a reference is broken levenshtein
|
||||
# distance is used to suggest an existing one. This is useful since IDs are
|
||||
# generated by Markdown from headers and thus edits alter them.
|
||||
#
|
||||
# Also detects duplicated IDs. They happen if there are headers with the same
|
||||
# text. Please do resolve them, if any, so guides are valid XHTML.
|
||||
#
|
||||
# ALL
|
||||
# Set to "1" to force the generation of all guides.
|
||||
#
|
||||
# ONLY
|
||||
# Use ONLY if you want to generate only one or a set of guides. Prefixes are
|
||||
# enough:
|
||||
#
|
||||
# # generates only association_basics.html
|
||||
# ONLY=assoc rake guides:generate
|
||||
#
|
||||
# Separate many using commas:
|
||||
#
|
||||
# # generates only association_basics.html and command_line.html
|
||||
# ONLY=assoc,command rake guides:generate
|
||||
#
|
||||
# Note that if you are working on a guide generation will by default process
|
||||
# only that one, so ONLY is rarely used nowadays.
|
||||
#
|
||||
# GUIDES_LANGUAGE
|
||||
# Use GUIDES_LANGUAGE when you want to generate translated guides in
|
||||
# <tt>source/<GUIDES_LANGUAGE></tt> folder (such as <tt>source/es</tt>).
|
||||
# Ignore it when generating English guides.
|
||||
#
|
||||
# EDGE
|
||||
# Set to "1" to indicate generated guides should be marked as edge. This
|
||||
# inserts a badge and changes the preamble of the home page.
|
||||
#
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
require "set"
|
||||
require "fileutils"
|
||||
|
||||
|
@ -64,46 +13,37 @@ require "rails_guides/levenshtein"
|
|||
|
||||
module RailsGuides
|
||||
class Generator
|
||||
attr_reader :guides_dir, :source_dir, :output_dir, :edge, :warnings, :all
|
||||
|
||||
GUIDES_RE = /\.(?:erb|md)\z/
|
||||
|
||||
def initialize(output = nil)
|
||||
set_flags_from_environment
|
||||
def initialize(edge:, version:, all:, only:, kindle:, language:)
|
||||
@edge = edge
|
||||
@version = version
|
||||
@all = all
|
||||
@only = only
|
||||
@kindle = kindle
|
||||
@language = language
|
||||
|
||||
if kindle?
|
||||
if @kindle
|
||||
check_for_kindlegen
|
||||
register_kindle_mime_types
|
||||
end
|
||||
|
||||
initialize_dirs(output)
|
||||
initialize_dirs
|
||||
create_output_dir_if_needed
|
||||
end
|
||||
|
||||
def set_flags_from_environment
|
||||
@edge = ENV["EDGE"] == "1"
|
||||
@warnings = ENV["WARNINGS"] == "1"
|
||||
@all = ENV["ALL"] == "1"
|
||||
@kindle = ENV["KINDLE"] == "1"
|
||||
@version = ENV["RAILS_VERSION"] || "local"
|
||||
@lang = ENV["GUIDES_LANGUAGE"]
|
||||
end
|
||||
|
||||
def register_kindle_mime_types
|
||||
Mime::Type.register_alias("application/xml", :opf, %w(opf))
|
||||
Mime::Type.register_alias("application/xml", :ncx, %w(ncx))
|
||||
initialize_markdown_renderer
|
||||
end
|
||||
|
||||
def generate
|
||||
generate_guides
|
||||
copy_assets
|
||||
generate_mobi if kindle?
|
||||
generate_mobi if @kindle
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def kindle?
|
||||
@kindle
|
||||
def register_kindle_mime_types
|
||||
Mime::Type.register_alias("application/xml", :opf, %w(opf))
|
||||
Mime::Type.register_alias("application/xml", :ncx, %w(ncx))
|
||||
end
|
||||
|
||||
def check_for_kindlegen
|
||||
|
@ -114,29 +54,35 @@ module RailsGuides
|
|||
|
||||
def generate_mobi
|
||||
require "rails_guides/kindle"
|
||||
out = "#{output_dir}/kindlegen.out"
|
||||
Kindle.generate(output_dir, mobi, out)
|
||||
out = "#{@output_dir}/kindlegen.out"
|
||||
Kindle.generate(@output_dir, mobi, out)
|
||||
puts "(kindlegen log at #{out})."
|
||||
end
|
||||
|
||||
def mobi
|
||||
"ruby_on_rails_guides_#@version%s.mobi" % (@lang.present? ? ".#@lang" : "")
|
||||
mobi = "ruby_on_rails_guides_#{@version || @edge[0, 7]}"
|
||||
mobi += ".#{@language}" if @language
|
||||
mobi += ".mobi"
|
||||
end
|
||||
|
||||
def initialize_dirs(output)
|
||||
@guides_dir = File.join(File.dirname(__FILE__), "..")
|
||||
@source_dir = "#@guides_dir/source/#@lang"
|
||||
@output_dir = if output
|
||||
output
|
||||
elsif kindle?
|
||||
"#@guides_dir/output/kindle/#@lang"
|
||||
else
|
||||
"#@guides_dir/output/#@lang"
|
||||
end.sub(%r</$>, "")
|
||||
def initialize_dirs
|
||||
@guides_dir = File.expand_path("..", __dir__)
|
||||
|
||||
@source_dir = "#{@guides_dir}/source"
|
||||
@source_dir += "/#{@language}" if @language
|
||||
|
||||
@output_dir = "#{@guides_dir}/output"
|
||||
@output_dir += "/kindle" if @kindle
|
||||
@source_dir += "/#{@language}" if @language
|
||||
end
|
||||
|
||||
def create_output_dir_if_needed
|
||||
FileUtils.mkdir_p(output_dir)
|
||||
FileUtils.mkdir_p(@output_dir)
|
||||
end
|
||||
|
||||
def initialize_markdown_renderer
|
||||
Markdown::Renderer.edge = @edge
|
||||
Markdown::Renderer.version = @version
|
||||
end
|
||||
|
||||
def generate_guides
|
||||
|
@ -147,27 +93,27 @@ module RailsGuides
|
|||
end
|
||||
|
||||
def guides_to_generate
|
||||
guides = Dir.entries(source_dir).grep(GUIDES_RE)
|
||||
guides = Dir.entries(@source_dir).grep(GUIDES_RE)
|
||||
|
||||
if kindle?
|
||||
Dir.entries("#{source_dir}/kindle").grep(GUIDES_RE).map do |entry|
|
||||
if @kindle
|
||||
Dir.entries("#{@source_dir}/kindle").grep(GUIDES_RE).map do |entry|
|
||||
next if entry == "KINDLE.md"
|
||||
guides << "kindle/#{entry}"
|
||||
end
|
||||
end
|
||||
|
||||
ENV.key?("ONLY") ? select_only(guides) : guides
|
||||
@only ? select_only(guides) : guides
|
||||
end
|
||||
|
||||
def select_only(guides)
|
||||
prefixes = ENV["ONLY"].split(",").map(&:strip)
|
||||
prefixes = @only.split(",").map(&:strip)
|
||||
guides.select do |guide|
|
||||
guide.start_with?("kindle".freeze, *prefixes)
|
||||
guide.start_with?("kindle", *prefixes)
|
||||
end
|
||||
end
|
||||
|
||||
def copy_assets
|
||||
FileUtils.cp_r(Dir.glob("#{guides_dir}/assets/*"), output_dir)
|
||||
FileUtils.cp_r(Dir.glob("#{@guides_dir}/assets/*"), @output_dir)
|
||||
end
|
||||
|
||||
def output_file_for(guide)
|
||||
|
@ -179,22 +125,28 @@ module RailsGuides
|
|||
end
|
||||
|
||||
def output_path_for(output_file)
|
||||
File.join(output_dir, File.basename(output_file))
|
||||
File.join(@output_dir, File.basename(output_file))
|
||||
end
|
||||
|
||||
def generate?(source_file, output_file)
|
||||
fin = File.join(source_dir, source_file)
|
||||
fin = File.join(@source_dir, source_file)
|
||||
fout = output_path_for(output_file)
|
||||
all || !File.exist?(fout) || File.mtime(fout) < File.mtime(fin)
|
||||
@all || !File.exist?(fout) || File.mtime(fout) < File.mtime(fin)
|
||||
end
|
||||
|
||||
def generate_guide(guide, output_file)
|
||||
output_path = output_path_for(output_file)
|
||||
puts "Generating #{guide} as #{output_file}"
|
||||
layout = kindle? ? "kindle/layout" : "layout"
|
||||
layout = @kindle ? "kindle/layout" : "layout"
|
||||
|
||||
File.open(output_path, "w") do |f|
|
||||
view = ActionView::Base.new(source_dir, edge: @edge, version: @version, mobi: "kindle/#{mobi}", lang: @lang)
|
||||
view = ActionView::Base.new(
|
||||
@source_dir,
|
||||
edge: @edge,
|
||||
version: @version,
|
||||
mobi: "kindle/#{mobi}",
|
||||
language: @language
|
||||
)
|
||||
view.extend(Helpers)
|
||||
|
||||
if guide =~ /\.(\w+)\.erb$/
|
||||
|
@ -202,10 +154,15 @@ module RailsGuides
|
|||
# Passing a template handler in the template name is deprecated. So pass the file name without the extension.
|
||||
result = view.render(layout: layout, formats: [$1], file: $`)
|
||||
else
|
||||
body = File.read(File.join(source_dir, guide))
|
||||
result = RailsGuides::Markdown.new(view, layout).render(body)
|
||||
body = File.read("#{@source_dir}/#{guide}")
|
||||
result = RailsGuides::Markdown.new(
|
||||
view: view,
|
||||
layout: layout,
|
||||
edge: @edge,
|
||||
version: @version
|
||||
).render(body)
|
||||
|
||||
warn_about_broken_links(result) if @warnings
|
||||
warn_about_broken_links(result)
|
||||
end
|
||||
|
||||
f.write(result)
|
||||
|
@ -231,7 +188,7 @@ module RailsGuides
|
|||
# Footnotes.
|
||||
anchors += Set.new(html.scan(/<p\s+class="footnote"\s+id="([^"]+)/).flatten)
|
||||
anchors += Set.new(html.scan(/<sup\s+class="footnote"\s+id="([^"]+)/).flatten)
|
||||
return anchors
|
||||
anchors
|
||||
end
|
||||
|
||||
def check_fragment_identifiers(html, anchors)
|
||||
|
|
|
@ -4,12 +4,14 @@ require "rails_guides/markdown/renderer"
|
|||
|
||||
module RailsGuides
|
||||
class Markdown
|
||||
def initialize(view, layout)
|
||||
@view = view
|
||||
@layout = layout
|
||||
def initialize(view:, layout:, edge:, version:)
|
||||
@view = view
|
||||
@layout = layout
|
||||
@edge = edge
|
||||
@version = version
|
||||
@index_counter = Hash.new(0)
|
||||
@raw_header = ""
|
||||
@node_ids = {}
|
||||
@raw_header = ""
|
||||
@node_ids = {}
|
||||
end
|
||||
|
||||
def render(body)
|
||||
|
@ -60,7 +62,8 @@ module RailsGuides
|
|||
autolink: true,
|
||||
strikethrough: true,
|
||||
superscript: true,
|
||||
tables: true)
|
||||
tables: true
|
||||
)
|
||||
end
|
||||
|
||||
def extract_raw_header_and_body
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
module RailsGuides
|
||||
class Markdown
|
||||
class Renderer < Redcarpet::Render::HTML
|
||||
def initialize(options = {})
|
||||
super
|
||||
end
|
||||
cattr_accessor :edge, :version
|
||||
|
||||
def block_code(code, language)
|
||||
<<-HTML
|
||||
|
@ -93,32 +91,30 @@ HTML
|
|||
end
|
||||
|
||||
def github_file_url(file_path)
|
||||
root, rest = file_path.split("/", 2)
|
||||
tree = version || edge
|
||||
|
||||
case root
|
||||
when "abstract_controller", "action_controller", "action_dispatch"
|
||||
path = ["actionpack", "lib", root, rest].join("/")
|
||||
when "active_support", "active_record", "active_model", "action_view",
|
||||
"action_cable", "action_mailer", "action_pack", "active_job"
|
||||
path = [root.sub("_", ""), "lib", root, rest].join("/")
|
||||
else
|
||||
path = file_path
|
||||
end
|
||||
root = file_path[%r{(.+)/}, 1]
|
||||
path = case root
|
||||
when "abstract_controller", "action_controller", "action_dispatch"
|
||||
"actionpack/lib/#{file_path}"
|
||||
when /\A(action|active)_/
|
||||
"#{root.sub("_", "")}/lib/#{file_path}"
|
||||
else
|
||||
file_path
|
||||
end
|
||||
|
||||
["https://github.com/rails/rails/tree", version || "master", path].join("/")
|
||||
end
|
||||
|
||||
def version
|
||||
ENV["RAILS_VERSION"]
|
||||
"https://github.com/rails/rails/tree/#{tree}/#{path}"
|
||||
end
|
||||
|
||||
def api_link(url)
|
||||
if version && !url.match(/v\d\.\d\.\d/)
|
||||
url.insert(url.index(".org") + 4, "/#{version}")
|
||||
url.sub("http://edgeapi", "http://api") if url.include?("edgeapi")
|
||||
if url =~ %r{http://api\.rubyonrails\.org/v\d+\.}
|
||||
url
|
||||
elsif edge
|
||||
url.sub("api", "edgeapi")
|
||||
else
|
||||
url.sub(/(?<=\.org)/, "/#{version}")
|
||||
end
|
||||
|
||||
url
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<h2>Ruby on Rails Guides (<%= @edge ? @version[0, 7] : @version %>)</h2>
|
||||
<h2>Ruby on Rails Guides (<%= @edge ? @edge[0, 7] : @version %>)</h2>
|
||||
|
||||
<% if @edge %>
|
||||
<p>
|
||||
These are <b>Edge Guides</b>, based on the current <a href="https://github.com/rails/rails/tree/<%= @version %>">master</a> branch.
|
||||
These are <b>Edge Guides</b>, based on <a href="https://github.com/rails/rails/tree/<%= @edge %>">master@<%= @edge[0, 7] %></a>.
|
||||
</p>
|
||||
<p>
|
||||
If you are looking for the ones for the stable version, please check
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<meta name="cover" content="cover" />
|
||||
<dc-metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
|
||||
<dc:title>Ruby on Rails Guides (<%= @version %>)</dc:title>
|
||||
<dc:title>Ruby on Rails Guides (<%= @version || "master@#{@edge[0, 7]}" %>)</dc:title>
|
||||
|
||||
<dc:language>en-us</dc:language>
|
||||
<dc:creator>Ruby on Rails</dc:creator>
|
||||
|
|
Loading…
Reference in New Issue